From d1bd4ec651b30f58a5889d1527499b53496509e2 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Fri, 1 Nov 2024 10:28:13 +0000 Subject: [PATCH 001/117] fix(developer): remove virtual key series --- developer/src/kmcmplib/src/Compiler.cpp | 2 ++ developer/src/kmcmplib/tests/gtest-compiler-test.cpp | 11 ++++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/developer/src/kmcmplib/src/Compiler.cpp b/developer/src/kmcmplib/src/Compiler.cpp index 57702ee1f0f..656a6e85840 100644 --- a/developer/src/kmcmplib/src/Compiler.cpp +++ b/developer/src/kmcmplib/src/Compiler.cpp @@ -2561,6 +2561,8 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX } while (iswspace(*q)) q++; + if (*q != ']') return KmnCompilerMessages::ERROR_InvalidToken; + break; /* out of while loop */ } tstr[mx++] = UC_SENTINEL_EXTENDEDEND; tstr[mx] = 0; diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index e6a5a0f513f..d9a3fb7526d 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -2029,13 +2029,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 K_C]"); + 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) From 86a6bf617ba4cef526bb19e919409afd7862605d Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Fri, 1 Nov 2024 10:40:58 +0000 Subject: [PATCH 002/117] fix(developer): remove redundant virtual key series while loop --- developer/src/kmcmplib/src/Compiler.cpp | 48 ++++++++++--------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/developer/src/kmcmplib/src/Compiler.cpp b/developer/src/kmcmplib/src/Compiler.cpp index 656a6e85840..8ea18abeac0 100644 --- a/developer/src/kmcmplib/src/Compiler.cpp +++ b/developer/src/kmcmplib/src/Compiler.cpp @@ -2498,27 +2498,22 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX 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(!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; - 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 */ + 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; + 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; + } else { for (j = 0; !iswspace(*q) && *q != ']' && *q != 0; q++, j++); if (*q == 0) return KmnCompilerMessages::ERROR_InvalidToken; @@ -2532,17 +2527,14 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX if (u16icmp(vkname, u"K_NPENTER") == 0) i = 5; // I649 - K_NPENTER hack - else - { - for (i = 0; i <= VK__MAX; i++) - { + else { + for (i = 0; i <= VK__MAX; i++) { if (u16icmp(vkname, VKeyNames[i]) == 0 || u16icmp(vkname, VKeyISO9995Names[i]) == 0) break; } } - if (i == VK__MAX + 1) - { + if (i == VK__MAX + 1) { if(!VerifyKeyboardVersion(fk, VERSION_90)) { return KmnCompilerMessages::ERROR_InvalidToken; } @@ -2552,8 +2544,6 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX return KmnCompilerMessages::ERROR_InvalidToken; } - p = q; - tstr[mx++] = (int)i; if (kmcmp::FMnemonicLayout && (i <= VK__MAX) && VKeyMayBeVCKey[i]) { @@ -2562,8 +2552,8 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX while (iswspace(*q)) q++; if (*q != ']') return KmnCompilerMessages::ERROR_InvalidToken; - break; /* out of while loop */ } + tstr[mx++] = UC_SENTINEL_EXTENDEDEND; tstr[mx] = 0; //printf("--EXTENDEDEND--\n"); From 72a27464f5a167f5db7c50afeafcee9ea83f5710 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Fri, 1 Nov 2024 10:48:49 +0000 Subject: [PATCH 003/117] fix(developer): refactor virtual key whitespace loop and improve layout --- developer/src/kmcmplib/src/Compiler.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/developer/src/kmcmplib/src/Compiler.cpp b/developer/src/kmcmplib/src/Compiler.cpp index 8ea18abeac0..1e3b457c27b 100644 --- a/developer/src/kmcmplib/src/Compiler.cpp +++ b/developer/src/kmcmplib/src/Compiler.cpp @@ -2502,17 +2502,22 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX 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; + 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; + + q++; // skip key + if (*q != chQuote) + return KmnCompilerMessages::ERROR_InvalidToken; + q++; // skip quote } else { for (j = 0; !iswspace(*q) && *q != ']' && *q != 0; q++, j++); @@ -2549,11 +2554,13 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX if (kmcmp::FMnemonicLayout && (i <= VK__MAX) && VKeyMayBeVCKey[i]) { ReportCompilerMessage(KmnCompilerMessages::WARN_VirtualKeyWithMnemonicLayout); // I3438 } - - while (iswspace(*q)) q++; - if (*q != ']') return KmnCompilerMessages::ERROR_InvalidToken; } + while (iswspace(*q)) q++; + + if (*q != ']') + return KmnCompilerMessages::ERROR_InvalidToken; + tstr[mx++] = UC_SENTINEL_EXTENDEDEND; tstr[mx] = 0; //printf("--EXTENDEDEND--\n"); From 94019b92b5c3c157985b2b9eb74fca8be90f79f2 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Fri, 1 Nov 2024 11:43:16 +0000 Subject: [PATCH 004/117] fix(developer): add wsRequired flag to check for whitespace between modifiers and modifier(s) and key --- developer/src/kmcmplib/src/Compiler.cpp | 33 ++++++++++--------- .../kmcmplib/tests/gtest-compiler-test.cpp | 30 ++++++++--------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/developer/src/kmcmplib/src/Compiler.cpp b/developer/src/kmcmplib/src/Compiler.cpp index 1e3b457c27b..b7b17725224 100644 --- a/developer/src/kmcmplib/src/Compiler.cpp +++ b/developer/src/kmcmplib/src/Compiler.cpp @@ -2034,6 +2034,7 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX int type, mx = 0, n, n1, n2, tokenFound = FALSE, z, sFlag = 0, j; KMX_DWORD i; KMX_BOOL finished = FALSE; + KMX_BOOL wsRequired = FALSE; KMX_WCHAR c; *tstr = 0; @@ -2412,50 +2413,53 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX } continue; case 11: - p++; sFlag = ISVIRTUALKEY /* 0 */; finished = FALSE; + p++; sFlag = ISVIRTUALKEY /* 0 */; finished = FALSE; wsRequired = FALSE; //printf("--EXTENDEDSTRING--\n"); do { + if (wsRequired && !iswspace(*p)) + return KmnCompilerMessages::ERROR_InvalidToken; // #12307 + while (iswspace(*p)) p++; switch (towupper(*p)) { case 'N': if (u16nicmp(p, u"NCAPS", 5) == 0) - sFlag |= NOTCAPITALFLAG, p += 5; + sFlag |= NOTCAPITALFLAG, wsRequired = TRUE, p += 5; else finished = TRUE; break; case 'L': if (u16nicmp(p, u"LALT", 4) == 0) - sFlag |= LALTFLAG, p += 4; + sFlag |= LALTFLAG, wsRequired = TRUE, p += 4; else if (u16nicmp(p, u"LCTRL", 5) == 0) - sFlag |= LCTRLFLAG, p += 5; + sFlag |= LCTRLFLAG, wsRequired = TRUE, p += 5; else finished = TRUE; break; case 'R': if (u16nicmp(p, u"RALT", 4) == 0) - sFlag |= RALTFLAG, p += 4; + sFlag |= RALTFLAG, wsRequired = TRUE, p += 4; else if (u16nicmp(p, u"RCTRL", 5) == 0) - sFlag |= RCTRLFLAG, p += 5; + sFlag |= RCTRLFLAG, wsRequired = TRUE, p += 5; else finished = TRUE; break; case 'A': if (u16nicmp(p, u"ALT", 3) == 0) - sFlag |= K_ALTFLAG, p += 3; + sFlag |= K_ALTFLAG, wsRequired = TRUE, p += 3; else finished = TRUE; break; case 'C': if (u16nicmp(p, u"CTRL", 4) == 0) - sFlag |= K_CTRLFLAG, p += 4; + sFlag |= K_CTRLFLAG, wsRequired = TRUE, p += 4; else if (u16nicmp(p, u"CAPS", 4) == 0) - sFlag |= CAPITALFLAG, p += 4; + sFlag |= CAPITALFLAG, wsRequired = TRUE, p += 4; else finished = TRUE; break; case 'S': if (u16nicmp(p, u"SHIFT", 5) == 0) - sFlag |= K_SHIFTFLAG, p += 5; + sFlag |= K_SHIFTFLAG, wsRequired = TRUE, p += 5; else finished = TRUE; break; default: @@ -2489,12 +2493,9 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX tstr[mx++] = CODE_EXTENDED; tstr[mx++] = sFlag; - while (iswspace(*p)) p++; - q = p; - if (*q == ']') - { + 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 } @@ -2509,7 +2510,9 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX 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; diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index d9a3fb7526d..ba66e313656 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -1807,25 +1807,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; @@ -2031,7 +2031,7 @@ TEST_F(CompilerTest, GetXStringImpl_type_osb_test) { // virtual key, in VKeyNames, multiple keys, KmnCompilerMessages::ERROR_InvalidToken (see #12307) fileKeyboard.version = VERSION_90; - u16cpy(str, u"[K_A K_B K_C]"); + u16cpy(str, u"[K_A K_B]"); EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidToken, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); } From ed42594b1aaff02bfc01cf6a4aa59f0507028a50 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Fri, 1 Nov 2024 12:10:39 +0000 Subject: [PATCH 005/117] fix(developer): minor layout changes --- developer/src/kmcmplib/src/Compiler.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/developer/src/kmcmplib/src/Compiler.cpp b/developer/src/kmcmplib/src/Compiler.cpp index b7b17725224..e878e4690ec 100644 --- a/developer/src/kmcmplib/src/Compiler.cpp +++ b/developer/src/kmcmplib/src/Compiler.cpp @@ -2524,13 +2524,15 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX } else { for (j = 0; !iswspace(*q) && *q != ']' && *q != 0; q++, j++); - if (*q == 0) return KmnCompilerMessages::ERROR_InvalidToken; + if (*q == 0) + return KmnCompilerMessages::ERROR_InvalidToken; KMX_WCHAR vkname[SZMAX_VKDICTIONARYNAME]; // I3438 - if (j >= SZMAX_VKDICTIONARYNAME) return KmnCompilerMessages::ERROR_InvalidToken; + if (j >= SZMAX_VKDICTIONARYNAME) + return KmnCompilerMessages::ERROR_InvalidToken; - u16ncpy(vkname, p, j); // I3481 + u16ncpy(vkname, p, j); // I3481 vkname[j] = 0; if (u16icmp(vkname, u"K_NPENTER") == 0) From 036ce049afa1a5bf860afe2fd5a0de279982f731 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Mon, 4 Nov 2024 10:28:53 +0000 Subject: [PATCH 006/117] chore(developer): update comments to remover TODO where virtual key section cannot be reached --- .../kmcmplib/tests/gtest-compiler-test.cpp | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index e6a5a0f513f..e60482db65b 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -787,7 +787,7 @@ TEST_F(CompilerTest, GetXStringImpl_type_double_quote_test) { 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 *** + // KmnCompilerMessages::ERROR_StringInVirtualKeySection (code cannot be reached) } // tests strings starting with single quote @@ -810,7 +810,7 @@ TEST_F(CompilerTest, GetXStringImpl_type_single_quote_test) { 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 *** + // KmnCompilerMessages::ERROR_StringInVirtualKeySection (code cannot be reached) } // tests strings starting with 'a' @@ -825,7 +825,7 @@ 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_AnyInVirtualKeySection (code cannot be reached) // KmnCompilerMessages::ERROR_InvalidAny, no delimiters => NULL u16cpy(str, u"any"); @@ -892,7 +892,7 @@ 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, KmnCompilerMessages::ERROR_BeepInVirtualKeySection (code cannot be reached) // beep, valid u16cpy(str, u"beep"); @@ -907,7 +907,7 @@ 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, KmnCompilerMessages::ERROR_InvalidInVirtualKeySection (code cannot be reached) // baselayout, no delimiters => NULL fileKeyboard.version = VERSION_90; @@ -980,7 +980,7 @@ 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, KmnCompilerMessages::ERROR_InvalidInVirtualKeySection (code cannot be reached) // if, no delimiters => NULL fileKeyboard.version = VERSION_80; @@ -1077,7 +1077,7 @@ 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, KmnCompilerMessages::ERROR_InvalidInVirtualKeySection (code cannot be reached) // index, no delimiters => NULL u16cpy(str, u"index"); @@ -1190,7 +1190,7 @@ 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, KmnCompilerMessages::ERROR_OutsInVirtualKeySection (code cannot be reached) // outs, no delimiters => NULL u16cpy(str, u"outs"); @@ -1266,7 +1266,7 @@ 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, KmnCompilerMessages::ERROR_ContextInVirtualKeySection (code cannot be reached) // context, no offset, valid fileKeyboard.version = VERSION_60; @@ -1352,7 +1352,7 @@ 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, KmnCompilerMessages::ERROR_CallInVirtualKeySection (code cannot be reached) // call, no delimiters => NULL fileKeyboard.version = VERSION_501; @@ -1443,7 +1443,7 @@ 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, KmnCompilerMessages::ERROR_AnyInVirtualKeySection (code cannot be reached) // notany, no delimiters => NULL fileKeyboard.version = VERSION_70; @@ -1629,7 +1629,7 @@ 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, KmnCompilerMessages::ERROR_InvalidInVirtualKeySection (code cannot be reached) // reset, no delimiters => NULL fileKeyboard.version = VERSION_80; From f4bd99f935d12b7528c8ff3ca46d08b212f9fd48 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 6 Nov 2024 10:59:29 +0700 Subject: [PATCH 007/117] fix(developer): reconnect --full-test in kmcmplib build and enable for CI The --full-test parameter in kmcmplib build.sh has not been working. This PR reconnects the parameter and also enables it by default for CI test builds (not release builds). Fixes: #12623 --- developer/src/kmcmplib/build.bat | 6 ++++- developer/src/kmcmplib/build.sh | 4 ++-- developer/src/kmcmplib/commands.inc.sh | 21 ++++++++++++++--- resources/build/build-utils-ci.inc.sh | 32 ++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 6 deletions(-) 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..f0a6686ba18 100755 --- a/developer/src/kmcmplib/build.sh +++ b/developer/src/kmcmplib/build.sh @@ -78,7 +78,7 @@ do_action() { done } -if builder_has_option --full-test; then +if should_do_full_test; then locate_keyboards_repo fi @@ -101,7 +101,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/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 From d88f16e1533a0bcd87ab0ec515cee2749013d9da Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 6 Nov 2024 11:09:14 +0700 Subject: [PATCH 008/117] chore(developer): include build-utils-ci.inc.sh in kmcmplib --- developer/src/kmcmplib/build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/developer/src/kmcmplib/build.sh b/developer/src/kmcmplib/build.sh index f0a6686ba18..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" From 3c680e3334db28fbb33d6661d01460a1287acd98 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 6 Nov 2024 12:57:55 +0700 Subject: [PATCH 009/117] fix(developer): normalize path separators in unit tests in kmcmplib While kmc did this already in its callbacks, the unit test callbacks did not, which meant that some keyboard tests failed on Linux and macOS. Relates-to: #12623 --- developer/src/kmcmplib/tests/util_callbacks.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) 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"); From 411cd06df72b1205bd96b6f73889e276e41fe06f Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 6 Nov 2024 13:34:28 +0700 Subject: [PATCH 010/117] fix(developer): use C.UTF-8 locale to for consistent cross-platform whitespace management On mac arch build, kmcmplib is failing to trim U+2002, unlike all other platforms. Using UTF-8 locale should treat the ISO 30112 POSIX space characters, which includes U+2002, as whitespace. --- developer/src/kmcmplib/src/CompilerInterfaces.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/developer/src/kmcmplib/src/CompilerInterfaces.cpp b/developer/src/kmcmplib/src/CompilerInterfaces.cpp index ba368028322..566e7a4b6c5 100644 --- a/developer/src/kmcmplib/src/CompilerInterfaces.cpp +++ b/developer/src/kmcmplib/src/CompilerInterfaces.cpp @@ -14,6 +14,8 @@ EXTERN bool kmcmp_CompileKeyboard( KMCMP_COMPILER_RESULT& result ) { + std::setlocale(LC_ALL, "C.UTF-8"); + FILE_KEYBOARD fk; fk.extra = new KMCMP_COMPILER_RESULT_EXTRA; fk.extra->kmnFilename = pszInfile; From 4e2f83ad509e5d63efd00e6127394bb5db7c4bb2 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 6 Nov 2024 13:39:12 +0700 Subject: [PATCH 011/117] chore(developer): skip anii and sil_kmhmu in full test anii.kmn and sil_kmhmu.kmn both have mismatching case in filename references for icons. For now, we will disable tests for these two keyboards, so that tests pass on Linux (which has case-sensitive filesystem). Note: the filename case was already addressed in the keyboards repo, so when we realign to a more recent commit for the test fixtures, we should be able to include these tests again. Relates-to: #12623 --- developer/src/kmcmplib/tests/get-test-source.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/developer/src/kmcmplib/tests/get-test-source.sh b/developer/src/kmcmplib/tests/get-test-source.sh index beebce3aca3..aa7d81d492e 100755 --- a/developer/src/kmcmplib/tests/get-test-source.sh +++ b/developer/src/kmcmplib/tests/get-test-source.sh @@ -9,5 +9,6 @@ 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' # #12623: exclude masaram_gondi due to #11806 +# #12630: exclude anii, sil_kmhmu as ico references have mismatching case \ No newline at end of file From 3a359b580a9f69433eed9bd136f030d0b15c8db5 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 6 Nov 2024 13:43:08 +0700 Subject: [PATCH 012/117] chore(developer): include clocale for CompilerInterfaces, for setlocale call --- developer/src/kmcmplib/src/CompilerInterfaces.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/developer/src/kmcmplib/src/CompilerInterfaces.cpp b/developer/src/kmcmplib/src/CompilerInterfaces.cpp index 566e7a4b6c5..71d72ac216e 100644 --- a/developer/src/kmcmplib/src/CompilerInterfaces.cpp +++ b/developer/src/kmcmplib/src/CompilerInterfaces.cpp @@ -1,4 +1,5 @@ #include "pch.h" +#include #include #include #include "kmcmplib.h" From 0df0287cb3a66117e731f4c2ede47701c296db2f Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 6 Nov 2024 13:56:41 +0700 Subject: [PATCH 013/117] chore(developer): remove setlocale again, add exclusions for fv_statimcets, fv_nuucaanul --- developer/src/kmcmplib/src/CompilerInterfaces.cpp | 4 ---- developer/src/kmcmplib/tests/get-test-source.sh | 6 ++++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/developer/src/kmcmplib/src/CompilerInterfaces.cpp b/developer/src/kmcmplib/src/CompilerInterfaces.cpp index 71d72ac216e..0e424c93b00 100644 --- a/developer/src/kmcmplib/src/CompilerInterfaces.cpp +++ b/developer/src/kmcmplib/src/CompilerInterfaces.cpp @@ -1,5 +1,4 @@ #include "pch.h" -#include #include #include #include "kmcmplib.h" @@ -14,9 +13,6 @@ EXTERN bool kmcmp_CompileKeyboard( const void* procContext, KMCMP_COMPILER_RESULT& result ) { - - std::setlocale(LC_ALL, "C.UTF-8"); - FILE_KEYBOARD fk; fk.extra = new KMCMP_COMPILER_RESULT_EXTRA; fk.extra->kmnFilename = pszInfile; diff --git a/developer/src/kmcmplib/tests/get-test-source.sh b/developer/src/kmcmplib/tests/get-test-source.sh index aa7d81d492e..a343bb7ff49 100755 --- a/developer/src/kmcmplib/tests/get-test-source.sh +++ b/developer/src/kmcmplib/tests/get-test-source.sh @@ -9,6 +9,8 @@ set -eu find "$1" -name '*.kmn' | \ grep -E '(release|experimental)/([a-z0-9_]+)/([a-z0-9_]+)/source/\3\.kmn$' | \ - grep -vE 'masaram_gondi|anii|sil_kmhmu' + grep -vE 'masaram_gondi|anii|sil_kmhmu|fv_statimcets|fv_nuucaanul' # #12623: exclude masaram_gondi due to #11806 -# #12630: exclude anii, sil_kmhmu as ico references have mismatching case \ No newline at end of file +# #12630: exclude anii, sil_kmhmu as ico references have mismatching case +# #12630: exclude fv_statimcets, fv_nuucaanul as these include U+2002 which is not +# treated as whitespace on mac arch \ No newline at end of file From 1c39a0e38fc9ece96e4b37cceed68c562072c9c7 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Thu, 7 Nov 2024 06:03:04 +0700 Subject: [PATCH 014/117] chore: fix PR number in comment --- developer/src/kmcmplib/tests/get-test-source.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/developer/src/kmcmplib/tests/get-test-source.sh b/developer/src/kmcmplib/tests/get-test-source.sh index a343bb7ff49..a195fc271dc 100755 --- a/developer/src/kmcmplib/tests/get-test-source.sh +++ b/developer/src/kmcmplib/tests/get-test-source.sh @@ -11,6 +11,6 @@ find "$1" -name '*.kmn' | \ grep -E '(release|experimental)/([a-z0-9_]+)/([a-z0-9_]+)/source/\3\.kmn$' | \ grep -vE 'masaram_gondi|anii|sil_kmhmu|fv_statimcets|fv_nuucaanul' # #12623: exclude masaram_gondi due to #11806 -# #12630: exclude anii, sil_kmhmu as ico references have mismatching case -# #12630: exclude fv_statimcets, fv_nuucaanul as these include U+2002 which is not +# #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 \ No newline at end of file From 1053c941b5f780edd9ae3e4f4a08e92f6af29f9a Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Fri, 8 Nov 2024 11:19:43 +1000 Subject: [PATCH 015/117] fix(windows): help links updated --- .../src/engine/keyman/viskbd/UfrmVisualKeyboard.pas | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas b/windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas index 53b2990b907..00ffa8026be 100644 --- a/windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas +++ b/windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas @@ -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,7 @@ procedure TfrmVisualKeyboard.BtnShowHint(Sender: TObject); procedure TfrmVisualKeyboard.BtnHelpClick(Sender: TObject); begin - TKeymanDesktopShell.OpenHelpJump('context_onscreenkeyboard', frmKeyman7Main.ActiveKeyboard); + TKeymanDesktopShell.OpenHelpJump('context/toolbox-onscreenkeyboard', frmKeyman7Main.ActiveKeyboard); end; procedure TfrmVisualKeyboard.BtnHideHint(Sender: TObject); From 47c712750ea0f2e07a9ab271a07be469f1c905cf Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 8 Nov 2024 09:54:40 +0700 Subject: [PATCH 016/117] docs(developer): kmc-generate Relates-to: #12641 --- .../docs/help/reference/kmc/cli/reference.md | 169 ++++++++++++++++++ 1 file changed, 169 insertions(+) diff --git a/developer/docs/help/reference/kmc/cli/reference.md b/developer/docs/help/reference/kmc/cli/reference.md index bff696d0d0d..848665ff590 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 message [message...]` : Describes one or more compiler messages in greater detail @@ -294,6 +306,163 @@ 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: keyboard name) + ## `kmc message` options One or more message identifiers can be specified for text or json formats. From 6caee57972b474a22dd882b8a0bcee4692e457aa Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Fri, 8 Nov 2024 20:29:24 +1000 Subject: [PATCH 017/117] fix(windows): add active page check to btnhelp --- windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas b/windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas index 00ffa8026be..b4c40aadb6c 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: @@ -1546,7 +1546,12 @@ procedure TfrmVisualKeyboard.BtnShowHint(Sender: TObject); procedure TfrmVisualKeyboard.BtnHelpClick(Sender: TObject); begin - TKeymanDesktopShell.OpenHelpJump('context/toolbox-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); From 61933f6d202d6547c8322ee7f532bf311b113165 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Fri, 8 Nov 2024 13:02:30 -0500 Subject: [PATCH 018/117] auto: increment master version to 18.0.139 --- HISTORY.md | 10 ++++++++++ VERSION.md | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 8c03d3470cd..1ed00fc84bb 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,15 @@ # Keyman Version History +## 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) diff --git a/VERSION.md b/VERSION.md index 2ef34fe0072..62b9f406197 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.138 \ No newline at end of file +18.0.139 \ No newline at end of file From 6fb31d2ba974ed52106deb7f038079c7471aa5d6 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Mon, 11 Nov 2024 09:03:40 +1000 Subject: [PATCH 019/117] fix(windows): stupid typo --- windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas b/windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas index b4c40aadb6c..c1d1dedaa0a 100644 --- a/windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas +++ b/windows/src/engine/keyman/viskbd/UfrmVisualKeyboard.pas @@ -640,7 +640,7 @@ function TfrmVisualKeyboard.FormHelp(Command: Word; Data: NativeInt; var CallHel case ActivePage of apKeyboard: TKeymanDesktopShell.OpenHelp('context/toolbox-onscreenkeyboard'); apCharacterMap: TKeymanDesktopShell.OpenHelp('context/toolbox-charactermap'); - apFontHelper: TKeymanDesktopShell.OpenHelp('context/toolbox-_fonthelper'); + apFontHelper: TKeymanDesktopShell.OpenHelp('context/toolbox-fonthelper'); apEntryHelper: TKeymanDesktopShell.OpenHelp('index'); end; end; @@ -1549,7 +1549,7 @@ procedure TfrmVisualKeyboard.BtnHelpClick(Sender: TObject); 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); + apFontHelper: TKeymanDesktopShell.OpenHelpJump('context/toolbox-fonthelper', frmKeyman7Main.ActiveKeyboard); apEntryHelper: TKeymanDesktopShell.OpenHelpJump('index', frmKeyman7Main.ActiveKeyboard); end; end; From f58683094ccbbf93108d0212f9632bf72bf03f8b Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Tue, 12 Nov 2024 14:37:12 +0700 Subject: [PATCH 020/117] chore(common): Add 17.0.330 - 17.0.332 to version history --- HISTORY.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 1ed00fc84bb..8ca6ca179c5 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -958,6 +958,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) From 8da5891b88423fa5c14f416574621b6140181ca8 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Tue, 12 Nov 2024 13:01:09 -0500 Subject: [PATCH 021/117] auto: increment master version to 18.0.140 --- HISTORY.md | 4 ++++ VERSION.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 1ed00fc84bb..b4f0ce1ed85 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Keyman Version History +## 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) diff --git a/VERSION.md b/VERSION.md index 62b9f406197..8434a7099e3 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.139 \ No newline at end of file +18.0.140 \ No newline at end of file From 5a93bdf6c2ad89017380f5fd0815678a22183eb0 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 13 Nov 2024 10:03:26 +0700 Subject: [PATCH 022/117] chore(developer): make package subfile description fully optional The package subfile description field is never really used in the end-user apps. As it is meaningless metadata, we'll make it fully optional, and start to remove all references in the designers and compilers. TODO: For packages targeting Keyman 18.0+, we should consider removing the description field altogether from the subfiles. --- common/web/types/build.sh | 2 +- common/web/types/src/package/kmp-json-file.ts | 2 +- .../web/utils/src/types/kps/kps-file.ts | 6 ++-- .../sil.ti_er.my_version.model.kps | 2 +- .../expected/kmhmu_2008/kmhmu_2024.kps | 2 +- .../kmc-package/src/compiler/kmp-compiler.ts | 8 ++--- .../src/compiler/kmp-inf-writer.ts | 2 +- ...e.qaa.sencoten.model.kmp.intermediate.json | 4 +-- .../test/fixtures/khmer_angkor/ref/kmp.json | 34 +++++++++--------- .../test/fixtures/kmp.json/kmp.json | 28 +++++++-------- .../test/fixtures/kmp_2.0/kmp.json | 36 +++++++++---------- ...s.qaa.sencoten.model.kmp.intermediate.json | 6 ++-- 12 files changed, 66 insertions(+), 66 deletions(-) diff --git a/common/web/types/build.sh b/common/web/types/build.sh index 7dac43dba81..b2ada0ecbc4 100755 --- a/common/web/types/build.sh +++ b/common/web/types/build.sh @@ -93,7 +93,7 @@ function do_test() { #------------------------------------------------------------------------------------------------------------------- -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/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/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/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-package/src/compiler/kmp-compiler.ts b/developer/src/kmc-package/src/compiler/kmp-compiler.ts index 3b50ee7ca39..5f6de5dc836 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: "" }); // 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" } ], From ce7593bd2f628f65ac7c38ebc376bff32b0e9df0 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 13 Nov 2024 09:59:43 +0700 Subject: [PATCH 023/117] fix(developer): box package compiler info fields If a .kps file had an `` element without a URL attribute, it would not map correctly in all circumstances. This change ensures that the kps-file-reader is responsible for normalizing the layout of these elements on read. --- .../common/web/utils/src/types/kps/kps-file-reader.ts | 11 +++++++++++ .../src/kmc-package/src/compiler/kmp-compiler.ts | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) 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/kmc-package/src/compiler/kmp-compiler.ts b/developer/src/kmc-package/src/compiler/kmp-compiler.ts index 5f6de5dc836..607823c7dd7 100644 --- a/developer/src/kmc-package/src/compiler/kmp-compiler.ts +++ b/developer/src/kmc-package/src/compiler/kmp-compiler.ts @@ -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(); From aa1c19c416bd8b782a1d2bd5abd15c191438bf8f Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 13 Nov 2024 10:21:36 +0700 Subject: [PATCH 024/117] docs: address review comments --- developer/docs/help/reference/kmc/cli/reference.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/developer/docs/help/reference/kmc/cli/reference.md b/developer/docs/help/reference/kmc/cli/reference.md index 848665ff590..f6fbc079aba 100644 --- a/developer/docs/help/reference/kmc/cli/reference.md +++ b/developer/docs/help/reference/kmc/cli/reference.md @@ -389,7 +389,8 @@ and the files in that folder will follow the `-n, --name ` : Keyboard descriptive name, referenced in the keyboard `` @@ -461,7 +462,7 @@ folder, and the files in that folder will follow the `-d, --description ` -: A short description of the project, in Markdown. (default: keyboard name) +: A short description of the project, in Markdown. (default: lexical model name) ## `kmc message` options From a33037b4df5da9eea38868ce83dc5a7a2c1e6005 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Wed, 13 Nov 2024 16:54:59 +0000 Subject: [PATCH 025/117] fix(developer): add basic_kbdcherp and basic_kbdolch to list of excluded keyboards --- developer/src/kmcmplib/tests/get-test-source.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/developer/src/kmcmplib/tests/get-test-source.sh b/developer/src/kmcmplib/tests/get-test-source.sh index a195fc271dc..fe6cded2f19 100755 --- a/developer/src/kmcmplib/tests/get-test-source.sh +++ b/developer/src/kmcmplib/tests/get-test-source.sh @@ -9,8 +9,10 @@ set -eu find "$1" -name '*.kmn' | \ grep -E '(release|experimental)/([a-z0-9_]+)/([a-z0-9_]+)/source/\3\.kmn$' | \ - grep -vE 'masaram_gondi|anii|sil_kmhmu|fv_statimcets|fv_nuucaanul' + 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 \ No newline at end of file +# treated as whitespace on mac arch +# #12604: exclude basic_kbdcherp, basic_kbdolch as these do not include now necessary +# whitespace, see also issue #12307 From f3fa7ade6f0f984f91af1cb4be4b3192a81ac2ff Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Wed, 13 Nov 2024 13:01:30 -0500 Subject: [PATCH 026/117] auto: increment master version to 18.0.141 --- HISTORY.md | 6 ++++++ VERSION.md | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index e2712544e3a..9d4b062fc8b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,11 @@ # Keyman Version History +## 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) diff --git a/VERSION.md b/VERSION.md index 8434a7099e3..5865806b91d 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.140 \ No newline at end of file +18.0.141 \ No newline at end of file From 34e314fdc9d3d3a2a2fda6b5d0c6c52bae83c0c3 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Thu, 14 Nov 2024 19:31:53 +0100 Subject: [PATCH 027/117] chore(linux): add support for Ubuntu 25.04 Plucky Puffin This change adds support for Plucky when building for llso/pso. #12614 already added support when building on Launchpad. --- .github/workflows/deb-packaging.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 From d6679cff386d2c11d5ec7833ad441a57ce5f6285 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Fri, 15 Nov 2024 13:02:18 -0500 Subject: [PATCH 028/117] auto: increment master version to 18.0.142 --- HISTORY.md | 4 ++++ VERSION.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 9d4b062fc8b..4b8b75802f0 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Keyman Version History +## 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) diff --git a/VERSION.md b/VERSION.md index 5865806b91d..e756675b009 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.141 \ No newline at end of file +18.0.142 \ No newline at end of file From dc3374f2168666fb72ae911288b1b61331c88ec3 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Tue, 19 Nov 2024 10:48:22 +0700 Subject: [PATCH 029/117] chore(common): Update CODEOWNERS update per session - add several to developer and to core --- docs/CODEOWNERS | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) 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 From 4b2641fc29518a9c35c092bf3074b025c1d16536 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 20 Nov 2024 07:58:14 +0700 Subject: [PATCH 030/117] chore(developer): cleanup fixtures for kmc-copy with optional attrs --- .../source/gff.ti_er.gff_tigrinya_eritrea.model.kps | 2 +- .../test/fixtures/projects/kmhmu_2008/source/kmhmu_2008.kps | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 From 49d1d9a5d911f1822b9ae1f8ed755d590707eaea Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Wed, 20 Nov 2024 13:01:16 -0500 Subject: [PATCH 031/117] auto: increment master version to 18.0.143 --- HISTORY.md | 4 ++++ VERSION.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 4b8b75802f0..29eb407ffde 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Keyman Version History +## 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) diff --git a/VERSION.md b/VERSION.md index e756675b009..2db67b55115 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.142 \ No newline at end of file +18.0.143 \ No newline at end of file From b7b70a0eafcd92ac900d30edf39ac47449dae6b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Nov 2024 08:51:07 +0000 Subject: [PATCH 032/117] chore(deps): bump cross-spawn from 7.0.3 to 7.0.6 Bumps [cross-spawn](https://github.com/moxystudio/node-cross-spawn) from 7.0.3 to 7.0.6. - [Changelog](https://github.com/moxystudio/node-cross-spawn/blob/master/CHANGELOG.md) - [Commits](https://github.com/moxystudio/node-cross-spawn/compare/v7.0.3...v7.0.6) --- updated-dependencies: - dependency-name: cross-spawn dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index dd9190fa8cd..efc2a0557ba 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", From 595fe46d0ba436c5f637c8b6bfe38a307a675598 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Nov 2024 12:48:10 +0000 Subject: [PATCH 033/117] chore(deps): bump cross-spawn Bumps [cross-spawn](https://github.com/moxystudio/node-cross-spawn) from 7.0.3 to 7.0.6. - [Changelog](https://github.com/moxystudio/node-cross-spawn/blob/master/CHANGELOG.md) - [Commits](https://github.com/moxystudio/node-cross-spawn/compare/v7.0.3...v7.0.6) --- updated-dependencies: - dependency-name: cross-spawn dependency-type: indirect ... Signed-off-by: dependabot[bot] --- .../src/win32/trayicon/addon-src/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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", From 38af9a500fcd54377cf832767bba2dc635e3a8ec Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Fri, 22 Nov 2024 13:01:23 -0500 Subject: [PATCH 034/117] auto: increment master version to 18.0.144 --- HISTORY.md | 4 ++++ VERSION.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 29eb407ffde..5a1289b064b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Keyman Version History +## 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) diff --git a/VERSION.md b/VERSION.md index 2db67b55115..113b99a4535 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.143 \ No newline at end of file +18.0.144 \ No newline at end of file From 5c704025e89713517976e321ce41978c3cc909b3 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Mon, 25 Nov 2024 16:11:12 +0100 Subject: [PATCH 035/117] chore(common): Add link to onboarding doc to `CONTRIBUTING.md` This is part of an action item from our Keyman conference. --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) 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 From bd6f30c1d338d989e5adbc34234a14fe37746fad Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Mon, 25 Nov 2024 13:01:53 -0500 Subject: [PATCH 036/117] auto: increment master version to 18.0.145 --- HISTORY.md | 7 +++++++ VERSION.md | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 5a1289b064b..aafdade9281 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,12 @@ # Keyman Version History +## 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) diff --git a/VERSION.md b/VERSION.md index 113b99a4535..e917147038f 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.144 \ No newline at end of file +18.0.145 \ No newline at end of file From f51bb9602b914bb96d02f652dcdd60b0d50de28c Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Tue, 26 Nov 2024 03:46:58 +0000 Subject: [PATCH 037/117] chore(developer): removed ERROR_XXXInVirtualKeySection from Compiler.cpp and kmn_compiler_errors.h --- .../src/common/include/kmn_compiler_errors.h | 16 ++++++++-------- developer/src/kmcmplib/src/Compiler.cpp | 15 --------------- 2 files changed, 8 insertions(+), 23 deletions(-) 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/kmcmplib/src/Compiler.cpp b/developer/src/kmcmplib/src/Compiler.cpp index e878e4690ec..a6b280aed14 100644 --- a/developer/src/kmcmplib/src/Compiler.cpp +++ b/developer/src/kmcmplib/src/Compiler.cpp @@ -2127,7 +2127,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; @@ -2137,7 +2136,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; @@ -2145,7 +2143,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; @@ -2167,7 +2164,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; @@ -2178,7 +2174,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; @@ -2195,7 +2190,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; @@ -2206,7 +2200,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); @@ -2241,7 +2234,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; @@ -2267,7 +2259,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); @@ -2303,7 +2294,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; @@ -2333,7 +2323,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; @@ -2391,7 +2380,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; @@ -2649,7 +2637,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; @@ -2661,7 +2648,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; @@ -2670,7 +2656,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; From f9f16167c1f8bc56d7abfc9d693292d9660d72f4 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Tue, 26 Nov 2024 03:59:59 +0000 Subject: [PATCH 038/117] chore(developer): made case 11 a block and moved sFlag, finished and wsRequired inside it --- developer/src/kmcmplib/src/Compiler.cpp | 264 ++++++++++++------------ 1 file changed, 134 insertions(+), 130 deletions(-) diff --git a/developer/src/kmcmplib/src/Compiler.cpp b/developer/src/kmcmplib/src/Compiler.cpp index a6b280aed14..c3164c4c367 100644 --- a/developer/src/kmcmplib/src/Compiler.cpp +++ b/developer/src/kmcmplib/src/Compiler.cpp @@ -2031,10 +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_BOOL wsRequired = FALSE; KMX_WCHAR c; *tstr = 0; @@ -2401,166 +2399,172 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX } continue; case 11: - p++; sFlag = ISVIRTUALKEY /* 0 */; finished = FALSE; wsRequired = FALSE; - - //printf("--EXTENDEDSTRING--\n"); - - do { - if (wsRequired && !iswspace(*p)) - return KmnCompilerMessages::ERROR_InvalidToken; // #12307 + int sFlag = ISVIRTUALKEY /* 0 */; + KMX_BOOL finished = FALSE; + KMX_BOOL wsRequired = FALSE; + + p++; - while (iswspace(*p)) p++; + //printf("--EXTENDEDSTRING--\n"); - switch (towupper(*p)) + do { - 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 (wsRequired && !iswspace(*p)) + return KmnCompilerMessages::ERROR_InvalidToken; // #12307 - if ((sFlag & (LCTRLFLAG | LALTFLAG)) && (sFlag & (RCTRLFLAG | RALTFLAG))) { - ReportCompilerMessage(KmnCompilerMessages::WARN_MixingLeftAndRightModifiers); - } + while (iswspace(*p)) p++; - // 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; + 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 ((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); - q = p; + tstr[mx++] = UC_SENTINEL; + tstr[mx++] = CODE_EXTENDED; + tstr[mx++] = sFlag; - 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 - } + q = p; - if (*q == '\'' || *q == '"') { - if(!VerifyKeyboardVersion(fk, VERSION_60)) { - return KmnCompilerMessages::ERROR_60FeatureOnly_VirtualCharKey; + 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 (!kmcmp::FMnemonicLayout) { - ReportCompilerMessage(KmnCompilerMessages::WARN_VirtualCharKeyWithPositionalLayout); - } + if (*q == '\'' || *q == '"') { + if(!VerifyKeyboardVersion(fk, VERSION_60)) { + return KmnCompilerMessages::ERROR_60FeatureOnly_VirtualCharKey; + } - KMX_WCHAR chQuote = *q; + if (!kmcmp::FMnemonicLayout) { + ReportCompilerMessage(KmnCompilerMessages::WARN_VirtualCharKeyWithPositionalLayout); + } - q++; // skip quote - if (*q == chQuote || *q == '\n' || *q == 0) - return KmnCompilerMessages::ERROR_InvalidToken; + KMX_WCHAR chQuote = *q; - tstr[mx - 1] |= VIRTUALCHARKEY; - tstr[mx++] = *q; + q++; // skip quote + if (*q == chQuote || *q == '\n' || *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++); + tstr[mx - 1] |= VIRTUALCHARKEY; + tstr[mx++] = *q; - 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; + } - tstr[mx++] = (int)i; + i = GetVKCode(fk, vkname); // I3438 + if (i == 0) + return KmnCompilerMessages::ERROR_InvalidToken; + } + + 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++; + while (iswspace(*q)) q++; - if (*q != ']') - return KmnCompilerMessages::ERROR_InvalidToken; + if (*q != ']') + return KmnCompilerMessages::ERROR_InvalidToken; - tstr[mx++] = UC_SENTINEL_EXTENDEDEND; - tstr[mx] = 0; - //printf("--EXTENDEDEND--\n"); + tstr[mx++] = UC_SENTINEL_EXTENDEDEND; + tstr[mx] = 0; + //printf("--EXTENDEDEND--\n"); - p = q + 1; + p = q + 1; - sFlag = 0; + sFlag = 0; + } continue; case 14: From 5adb76b3571ee874a493ee64aa5299bafa841f54 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Tue, 26 Nov 2024 04:04:13 +0000 Subject: [PATCH 039/117] chore(developer): removed comments referencing ERROR_XXXInVirtualKeySection from gtest-compiler-test.cpp --- .../kmcmplib/tests/gtest-compiler-test.cpp | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index a7d06ea7ede..ca8f40f6d81 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.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 (code cannot be reached) } // 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 (code cannot be reached) } // 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 (code cannot be reached) - // 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 (code cannot be reached) - // 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 (code cannot be reached) - // 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 (code cannot be reached) - // 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 (code cannot be reached) - // 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 (code cannot be reached) - // 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 (code cannot be reached) - // 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 (code cannot be reached) - // 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 (code cannot be reached) - // 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 (code cannot be reached) - // reset, no delimiters => NULL fileKeyboard.version = VERSION_80; u16cpy(str, u"reset"); From 7a53c892778ca9019ceecc5718a803db2e419fc9 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:13:16 +1000 Subject: [PATCH 040/117] docs(windows): update emscripten bash setup --- docs/build/windows.md | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) 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 From f18bba2781a17af9ace107a048ac1d0eea805fe1 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Tue, 26 Nov 2024 16:20:43 +1000 Subject: [PATCH 041/117] docs(linux): update emscripten bash setup Update the linux and macos bash setup to documents. --- docs/build/linux-ubuntu.md | 13 +++++++++++++ docs/build/macos.md | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/docs/build/linux-ubuntu.md b/docs/build/linux-ubuntu.md index a45d9390ba5..a7f15a29e0c 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 +cd upstream/emscripten +npm install export EMSCRIPTEN_BASE="$(pwd)/upstream/emscripten" 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..2baf0d5831a 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 +cd upstream/emscripten +npm install export EMSCRIPTEN_BASE="$(pwd)/upstream/emscripten" 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] From c6ef37fdefb287e966bc9d1f2095fdf4bb41e469 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Tue, 26 Nov 2024 06:57:44 +0000 Subject: [PATCH 042/117] chore(developer): remove ERROR_XXXInVirtualKeySection from kmn-compiler-messages.ts --- .../src/compiler/kmn-compiler-messages.ts | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) 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`); From 2cb2e8c4fb8a272e38cd7744aad2b9d5a39d8dc0 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Tue, 26 Nov 2024 08:08:15 +0000 Subject: [PATCH 043/117] chore(developer): initial commit of test-string-lists.ts --- common/web/types/.gitignore | 3 ++- .../web/types/test/ldml-keyboard/test-string-list.ts | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 common/web/types/test/ldml-keyboard/test-string-list.ts 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/test/ldml-keyboard/test-string-list.ts b/common/web/types/test/ldml-keyboard/test-string-list.ts new file mode 100644 index 00000000000..ea29249d7ef --- /dev/null +++ b/common/web/types/test/ldml-keyboard/test-string-list.ts @@ -0,0 +1,11 @@ +import 'mocha'; +import { assert } from 'chai'; +//import { ListIndex, ListItem } from '../../src/ldml-keyboard/string-list.js'; + +describe('Test of String-List', () => { + describe('should test ultimate truth', () => { + it('the truth', () => { + assert.isTrue(true); + }); + }); +}); \ No newline at end of file From d86e499f9c81cff862ff2b15ffcc983e0bb356d9 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Tue, 26 Nov 2024 18:47:44 +1000 Subject: [PATCH 044/117] docs(common): apply review comments Co-authored-by: Eberhard Beilharz Co-authored-by: Marc Durdin --- docs/build/linux-ubuntu.md | 2 +- docs/build/macos.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/build/linux-ubuntu.md b/docs/build/linux-ubuntu.md index a7f15a29e0c..37b2aafa1ab 100644 --- a/docs/build/linux-ubuntu.md +++ b/docs/build/linux-ubuntu.md @@ -72,7 +72,7 @@ cd emsdk ./emsdk activate 3.1.58 cd upstream/emscripten npm install -export EMSCRIPTEN_BASE="$(pwd)/upstream/emscripten" +export EMSCRIPTEN_BASE="$(pwd)" echo "export EMSCRIPTEN_BASE=\"$EMSCRIPTEN_BASE\"" >> .bashrc ``` diff --git a/docs/build/macos.md b/docs/build/macos.md index 2baf0d5831a..f961942070b 100644 --- a/docs/build/macos.md +++ b/docs/build/macos.md @@ -103,7 +103,7 @@ emsdk install 3.1.58 emsdk activate 3.1.58 cd upstream/emscripten npm install -export EMSCRIPTEN_BASE="$(pwd)/upstream/emscripten" +export EMSCRIPTEN_BASE="$(pwd)" echo "export EMSCRIPTEN_BASE=\"$EMSCRIPTEN_BASE\"" >> .bashrc ``` From fa4f1e5d0fc7acb8c41c4787c68a4df13f8b1bd2 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Tue, 26 Nov 2024 08:50:36 +0000 Subject: [PATCH 045/117] chore(developer): add one ListItem test case --- .../web/types/test/ldml-keyboard/test-string-list.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/common/web/types/test/ldml-keyboard/test-string-list.ts b/common/web/types/test/ldml-keyboard/test-string-list.ts index ea29249d7ef..0f73bbf93fd 100644 --- a/common/web/types/test/ldml-keyboard/test-string-list.ts +++ b/common/web/types/test/ldml-keyboard/test-string-list.ts @@ -1,11 +1,14 @@ import 'mocha'; import { assert } from 'chai'; //import { ListIndex, ListItem } from '../../src/ldml-keyboard/string-list.js'; +import { ListItem } from '../../src/ldml-keyboard/string-list.js'; describe('Test of String-List', () => { - describe('should test ultimate truth', () => { - it('the truth', () => { - assert.isTrue(true); + describe('should test ListItem', () => { + it('fromStrings returns an empty ListItem if source is null', () => { + const actual = ListItem.fromStrings(null, null, null); + const expected = new ListItem(); + assert.deepEqual(actual, expected); }); }); -}); \ No newline at end of file +}); From 432ab7055f43ec3747f1614c5a0948b35d271f49 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Tue, 26 Nov 2024 11:04:01 +0100 Subject: [PATCH 046/117] chore(web): rename test files and folders This change renames the test files for Web according to the discussion at the Keyman conference in November 2024. It also renames some folders from `test` to `tests`. --- web/build.sh | 4 ++-- web/src/engine/common/web-utils/.c8rc.json | 2 +- web/src/engine/common/web-utils/.gitignore | 1 - web/src/engine/common/web-utils/build.sh | 2 +- .../deepCopy.js => tests/deepCopy.tests.js} | 0 .../managedPromise.tests.js} | 0 .../priorityQueue.tests.js} | 0 .../timeoutPromise.tests.js} | 0 .../versions.js => tests/versions.tests.js} | 0 web/src/engine/common/web-utils/tsconfig.json | 2 +- .../predictive-text/templates/.c8rc.json | 2 +- .../engine/predictive-text/templates/build.sh | 2 +- .../predictive-text/templates/package.json | 2 +- .../test-common.js => tests/common.tests.js} | 0 .../{test => tests}/custom-breakers.def.js | 0 .../fixtures/tries/accented.json | 0 .../fixtures/tries/english-1000.json | 0 .../fixtures/tries/smp-apple.json | 0 .../templates/{test => tests}/helpers.js | 0 .../quote-behavior.tests.js} | 0 .../tokenization.tests.js} | 0 .../trie-model.tests.js} | 0 .../trie-traversal.tests.js} | 0 .../predictive-text/templates/tsconfig.json | 2 +- .../predictive-text/wordbreakers/.c8rc.json | 2 +- .../predictive-text/wordbreakers/build.sh | 8 ++++--- .../predictive-text/wordbreakers/package.json | 2 +- .../ascii-word-breaker.tests.js} | 0 .../default-word-breaker.tests.js} | 0 .../placeholder-word-breaker.tests.js} | 0 .../search-property.tests.js} | 0 ...romise-store.js => promise-store.tests.js} | 0 ...-lmlayer.js => top-level-lmlayer.tests.js} | 0 ...n.js => worker-dummy-integration.tests.js} | 0 ...on.js => worker-trie-integration.tests.js} | 0 ...yer.spec.ts => top-level-lmlayer.tests.ts} | 0 ...c.ts => worker-dummy-integration.tests.ts} | 0 ...ec.ts => worker-trie-integration.tests.ts} | 0 .../in_browser/web-test-runner.config.mjs | 2 +- .../predictive-text/worker-thread/.c8rc.json | 2 +- .../predictive-text/worker-thread/build.sh | 4 ++-- .../mocha/cases/auto-correct.js | 0 .../mocha/cases/casing-detection.js | 0 .../cases/early-correction-search-stopping.js | 0 .../edit-distance/classical-calculation.js | 0 .../cases/edit-distance/context-tracker.js | 0 .../cases/edit-distance/distance-modeler.js | 0 .../cases/edit-distance/execution-timer.js | 0 .../mocha/cases/predict-from-corrections.js | 0 .../mocha/cases/suggestion-deduplication.js | 0 .../mocha/cases/suggestion-finalization.js | 0 .../mocha/cases/suggestion-similarity.js | 0 .../mocha/cases/transform-tokenization.js | 0 .../mocha/cases/transform-utils.js | 0 .../mocha/cases/worker-custom-punctuation.js | 0 .../mocha/cases/worker-initialization.js | 0 .../mocha/cases/worker-model-compositor.js | 0 .../mocha/cases/worker-predict-dummy.js | 0 .../mocha/cases/worker-predict.js | 0 .../test-runner/cases/worker.tests.ts} | 0 .../test-runner/web-test-runner.CI.config.mjs | 0 .../test-runner/web-test-runner.config.mjs | 2 +- ...html => outputTargetForElement.tests.html} | 0 ....spec.ts => pageContextAttachment.test.ts} | 0 ...anager.spec.ts => contextManager.tests.ts} | 0 .../{cookies.spec.ts => cookies.tests.ts} | 0 ...es.spec.ts => element_interfaces.tests.ts} | 0 ...et_mocks.spec.ts => target_mocks.tests.ts} | 0 .../{canary.spec.ts => canary.tests.ts} | 0 ...st-page.spec.html => host-page.tests.html} | 6 ++--- ...dInputs.spec.ts => ignoredInputs.tests.ts} | 0 ...pec.ts => recordedCoordSequences.tests.ts} | 0 ...dQueries.spec.ts => cloudQueries.tests.ts} | 0 ...ter.spec.ts => domCloudRequester.tests.ts} | 0 ...spec.ts => keyboardRequisitioner.tests.ts} | 0 ...der.spec.ts => domKeyboardLoader.tests.ts} | 0 ...activation.spec.ts => activation.tests.ts} | 0 .../osk/{events.spec.ts => events.tests.ts} | 0 ...init_check.spec.ts => init_check.tests.ts} | 0 .../test/auto/dom/web-test-runner.config.mjs | 24 +++++++++---------- ...enerSpy.js => emitterListenerSpy.tests.js} | 0 ...Emitter.js => legacyEventEmitter.tests.js} | 0 ...guration.js => pathConfiguration.tests.js} | 0 ...ext.spec.js => predictionContext.tests.js} | 0 ...{basic-engine.js => basic-engine.tests.js} | 0 .../{basic-init.js => basic-init.tests.js} | 0 ...dled-module.js => bundled-module.tests.js} | 0 .../{chirality.js => chirality.tests.js} | 0 .../{deadkeys.js => deadkeys.tests.js} | 0 .../engine/{context.js => context.tests.js} | 0 ...any_context.js => notany_context.tests.js} | 0 .../engine/{stores.js => stores.tests.js} | 0 ...roup.js => unmatched_final_group.tests.js} | 0 .../js-processor/{mocks.js => mocks.tests.js} | 0 ...rules.js => non-positional-rules.tests.js} | 0 ...pace.js => specialized-backspace.tests.js} | 0 ...nscriptions.js => transcriptions.tests.js} | 0 ...{cloudQueries.js => cloudQueries.tests.js} | 0 ...oner.js => keyboardRequisitioner.tests.js} | 0 ...{keyboardStub.js => keyboardStub.tests.js} | 0 ...quester.js => nodeCloudRequester.tests.js} | 0 ...Cache.js => stubAndKeyboardCache.tests.js} | 0 ...d-loading.js => keyboard-loading.tests.js} | 0 ...erties.js => keyboard-properties.tests.js} | 0 ...cessor.spec.js => inputProcessor.tests.js} | 0 ...sor.spec.js => languageProcessor.tests.js} | 0 .../cases/{basics.spec.ts => basics.tests.ts} | 0 .../cases/{engine.spec.ts => engine.tests.ts} | 0 ...lity.spec.ts => engine_chirality.tests.ts} | 0 .../cases/{events.spec.ts => events.tests.ts} | 0 ...ection.spec.ts => text_selection.tests.ts} | 0 ...init_check.spec.ts => init_check.tests.ts} | 0 .../integrated/web-test-runner.config.mjs | 6 ++--- 113 files changed, 39 insertions(+), 38 deletions(-) rename web/src/engine/common/web-utils/src/{test/deepCopy.js => tests/deepCopy.tests.js} (100%) rename web/src/engine/common/web-utils/src/{test/managedPromise.js => tests/managedPromise.tests.js} (100%) rename web/src/engine/common/web-utils/src/{test/priorityQueue.js => tests/priorityQueue.tests.js} (100%) rename web/src/engine/common/web-utils/src/{test/timeoutPromise.js => tests/timeoutPromise.tests.js} (100%) rename web/src/engine/common/web-utils/src/{test/versions.js => tests/versions.tests.js} (100%) rename web/src/engine/predictive-text/templates/{test/test-common.js => tests/common.tests.js} (100%) rename web/src/engine/predictive-text/templates/{test => tests}/custom-breakers.def.js (100%) rename web/src/engine/predictive-text/templates/{test => tests}/fixtures/tries/accented.json (100%) rename web/src/engine/predictive-text/templates/{test => tests}/fixtures/tries/english-1000.json (100%) rename web/src/engine/predictive-text/templates/{test => tests}/fixtures/tries/smp-apple.json (100%) rename web/src/engine/predictive-text/templates/{test => tests}/helpers.js (100%) rename web/src/engine/predictive-text/templates/{test/test-quote-behavior.js => tests/quote-behavior.tests.js} (100%) rename web/src/engine/predictive-text/templates/{test/test-tokenization.js => tests/tokenization.tests.js} (100%) rename web/src/engine/predictive-text/templates/{test/test-trie-model.js => tests/trie-model.tests.js} (100%) rename web/src/engine/predictive-text/templates/{test/test-trie-traversal.js => tests/trie-traversal.tests.js} (100%) rename web/src/engine/predictive-text/wordbreakers/{test/test-ascii-word-breaker.js => tests/ascii-word-breaker.tests.js} (100%) rename web/src/engine/predictive-text/wordbreakers/{test/test-default-word-breaker.js => tests/default-word-breaker.tests.js} (100%) rename web/src/engine/predictive-text/wordbreakers/{test/test-placeholder-word-breaker.js => tests/placeholder-word-breaker.tests.js} (100%) rename web/src/engine/predictive-text/wordbreakers/{test/test-search-property.js => tests/search-property.tests.js} (100%) rename web/src/engine/predictive-text/worker-main/unit_tests/headless/{promise-store.js => promise-store.tests.js} (100%) rename web/src/engine/predictive-text/worker-main/unit_tests/headless/{top-level-lmlayer.js => top-level-lmlayer.tests.js} (100%) rename web/src/engine/predictive-text/worker-main/unit_tests/headless/{worker-dummy-integration.js => worker-dummy-integration.tests.js} (100%) rename web/src/engine/predictive-text/worker-main/unit_tests/headless/{worker-trie-integration.js => worker-trie-integration.tests.js} (100%) rename web/src/engine/predictive-text/worker-main/unit_tests/in_browser/cases/{top-level-lmlayer.spec.ts => top-level-lmlayer.tests.ts} (100%) rename web/src/engine/predictive-text/worker-main/unit_tests/in_browser/cases/{worker-dummy-integration.spec.ts => worker-dummy-integration.tests.ts} (100%) rename web/src/engine/predictive-text/worker-main/unit_tests/in_browser/cases/{worker-trie-integration.spec.ts => worker-trie-integration.tests.ts} (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/mocha/cases/auto-correct.js (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/mocha/cases/casing-detection.js (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/mocha/cases/early-correction-search-stopping.js (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/mocha/cases/edit-distance/classical-calculation.js (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/mocha/cases/edit-distance/context-tracker.js (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/mocha/cases/edit-distance/distance-modeler.js (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/mocha/cases/edit-distance/execution-timer.js (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/mocha/cases/predict-from-corrections.js (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/mocha/cases/suggestion-deduplication.js (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/mocha/cases/suggestion-finalization.js (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/mocha/cases/suggestion-similarity.js (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/mocha/cases/transform-tokenization.js (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/mocha/cases/transform-utils.js (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/mocha/cases/worker-custom-punctuation.js (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/mocha/cases/worker-initialization.js (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/mocha/cases/worker-model-compositor.js (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/mocha/cases/worker-predict-dummy.js (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/mocha/cases/worker-predict.js (100%) rename web/src/engine/predictive-text/worker-thread/src/{test/test-runner/cases/worker.spec.ts => tests/test-runner/cases/worker.tests.ts} (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/test-runner/web-test-runner.CI.config.mjs (100%) rename web/src/engine/predictive-text/worker-thread/src/{test => tests}/test-runner/web-test-runner.config.mjs (99%) rename web/src/test/auto/dom/cases/attachment/{outputTargetForElement.spec.html => outputTargetForElement.tests.html} (100%) rename web/src/test/auto/dom/cases/attachment/{pageContextAttachment.spec.ts => pageContextAttachment.test.ts} (100%) rename web/src/test/auto/dom/cases/browser/{contextManager.spec.ts => contextManager.tests.ts} (100%) rename web/src/test/auto/dom/cases/dom-utils/{cookies.spec.ts => cookies.tests.ts} (100%) rename web/src/test/auto/dom/cases/element-wrappers/{element_interfaces.spec.ts => element_interfaces.tests.ts} (100%) rename web/src/test/auto/dom/cases/element-wrappers/{target_mocks.spec.ts => target_mocks.tests.ts} (100%) rename web/src/test/auto/dom/cases/gesture-processor/{canary.spec.ts => canary.tests.ts} (100%) rename web/src/test/auto/dom/cases/gesture-processor/{host-page.spec.html => host-page.tests.html} (92%) rename web/src/test/auto/dom/cases/gesture-processor/{ignoredInputs.spec.ts => ignoredInputs.tests.ts} (100%) rename web/src/test/auto/dom/cases/gesture-processor/{recordedCoordSequences.spec.ts => recordedCoordSequences.tests.ts} (100%) rename web/src/test/auto/dom/cases/keyboard-storage/{cloudQueries.spec.ts => cloudQueries.tests.ts} (100%) rename web/src/test/auto/dom/cases/keyboard-storage/{domCloudRequester.spec.ts => domCloudRequester.tests.ts} (100%) rename web/src/test/auto/dom/cases/keyboard-storage/{keyboardRequisitioner.spec.ts => keyboardRequisitioner.tests.ts} (100%) rename web/src/test/auto/dom/cases/keyboard/{domKeyboardLoader.spec.ts => domKeyboardLoader.tests.ts} (100%) rename web/src/test/auto/dom/cases/osk/{activation.spec.ts => activation.tests.ts} (100%) rename web/src/test/auto/dom/cases/osk/{events.spec.ts => events.tests.ts} (100%) rename web/src/test/auto/dom/{test_init_check.spec.ts => init_check.tests.ts} (100%) rename web/src/test/auto/headless/engine/events/{emitterListenerSpy.js => emitterListenerSpy.tests.js} (100%) rename web/src/test/auto/headless/engine/events/{legacyEventEmitter.js => legacyEventEmitter.tests.js} (100%) rename web/src/test/auto/headless/engine/interfaces/{pathConfiguration.js => pathConfiguration.tests.js} (100%) rename web/src/test/auto/headless/engine/interfaces/prediction/{predictionContext.spec.js => predictionContext.tests.js} (100%) rename web/src/test/auto/headless/engine/js-processor/{basic-engine.js => basic-engine.tests.js} (100%) rename web/src/test/auto/headless/engine/js-processor/{basic-init.js => basic-init.tests.js} (100%) rename web/src/test/auto/headless/engine/js-processor/{bundled-module.js => bundled-module.tests.js} (100%) rename web/src/test/auto/headless/engine/js-processor/{chirality.js => chirality.tests.js} (100%) rename web/src/test/auto/headless/engine/js-processor/{deadkeys.js => deadkeys.tests.js} (100%) rename web/src/test/auto/headless/engine/js-processor/engine/{context.js => context.tests.js} (100%) rename web/src/test/auto/headless/engine/js-processor/engine/{notany_context.js => notany_context.tests.js} (100%) rename web/src/test/auto/headless/engine/js-processor/engine/{stores.js => stores.tests.js} (100%) rename web/src/test/auto/headless/engine/js-processor/engine/{unmatched_final_group.js => unmatched_final_group.tests.js} (100%) rename web/src/test/auto/headless/engine/js-processor/{mocks.js => mocks.tests.js} (100%) rename web/src/test/auto/headless/engine/js-processor/{non-positional-rules.js => non-positional-rules.tests.js} (100%) rename web/src/test/auto/headless/engine/js-processor/{specialized-backspace.js => specialized-backspace.tests.js} (100%) rename web/src/test/auto/headless/engine/js-processor/{transcriptions.js => transcriptions.tests.js} (100%) rename web/src/test/auto/headless/engine/keyboard-storage/{cloudQueries.js => cloudQueries.tests.js} (100%) rename web/src/test/auto/headless/engine/keyboard-storage/{keyboardRequisitioner.js => keyboardRequisitioner.tests.js} (100%) rename web/src/test/auto/headless/engine/keyboard-storage/{keyboardStub.js => keyboardStub.tests.js} (100%) rename web/src/test/auto/headless/engine/keyboard-storage/{nodeCloudRequester.js => nodeCloudRequester.tests.js} (100%) rename web/src/test/auto/headless/engine/keyboard-storage/{stubAndKeyboardCache.js => stubAndKeyboardCache.tests.js} (100%) rename web/src/test/auto/headless/engine/keyboard/{keyboard-loading.js => keyboard-loading.tests.js} (100%) rename web/src/test/auto/headless/engine/keyboard/{keyboard-properties.js => keyboard-properties.tests.js} (100%) rename web/src/test/auto/headless/engine/main/headless/{inputProcessor.spec.js => inputProcessor.tests.js} (100%) rename web/src/test/auto/headless/engine/main/headless/{languageProcessor.spec.js => languageProcessor.tests.js} (100%) rename web/src/test/auto/integrated/cases/{basics.spec.ts => basics.tests.ts} (100%) rename web/src/test/auto/integrated/cases/{engine.spec.ts => engine.tests.ts} (100%) rename web/src/test/auto/integrated/cases/{engine_chirality.spec.ts => engine_chirality.tests.ts} (100%) rename web/src/test/auto/integrated/cases/{events.spec.ts => events.tests.ts} (100%) rename web/src/test/auto/integrated/cases/{text_selection.spec.ts => text_selection.tests.ts} (100%) rename web/src/test/auto/integrated/{test_init_check.spec.ts => init_check.tests.ts} (100%) diff --git a/web/build.sh b/web/build.sh index 6f1846dc6a4..d01d493517c 100755 --- a/web/build.sh +++ b/web/build.sh @@ -55,7 +55,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" \ @@ -127,7 +127,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/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/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/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/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/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/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/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.test.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.test.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/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/keyboard/domKeyboardLoader.spec.ts b/web/src/test/auto/dom/cases/keyboard/domKeyboardLoader.tests.ts similarity index 100% rename from web/src/test/auto/dom/cases/keyboard/domKeyboardLoader.spec.ts rename to web/src/test/auto/dom/cases/keyboard/domKeyboardLoader.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 3050837cd55..701eab15a7d 100644 --- a/web/src/test/auto/dom/web-test-runner.config.mjs +++ b/web/src/test/auto/dom/web-test-runner.config.mjs @@ -33,53 +33,53 @@ export default { nodeResolve: true, // Top-level, implicit 'default' group files: [ - 'src/test/auto/dom/test_init_check.spec.ts', - // '**/*.spec.html' + 'src/test/auto/dom/init_check.tests.ts', + // '**/*.tests.html' ], groups: [ { name: 'engine/attachment', // Relative, from the containing package.json files: [ - 'build/test/dom/cases/attachment/**/*.spec.html', - 'build/test/dom/cases/attachment/**/*.spec.mjs' + 'build/test/dom/cases/attachment/**/*.tests.html', + 'build/test/dom/cases/attachment/**/*.tests.mjs' ] }, { name: 'app/browser', // Relative, from the containing package.json - files: ['build/test/dom/cases/browser/**/*.spec.mjs'] + files: ['build/test/dom/cases/browser/**/*.tests.mjs'] }, { name: 'engine/dom-utils', // Relative, from the containing package.json - files: ['build/test/dom/cases/dom-utils/**/*.spec.mjs'] + files: ['build/test/dom/cases/dom-utils/**/*.tests.mjs'] }, { name: 'engine/element-wrappers', // Relative, from the containing package.json - files: ['build/test/dom/cases/element-wrappers/**/*.spec.mjs'] + files: ['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: ['src/test/auto/dom/cases/gesture-processor/**/*.spec.html'] + // Note: here we use the .tests.html file in the src directory! + files: ['src/test/auto/dom/cases/gesture-processor/**/*.tests.html'] }, { name: 'engine/keyboard', // Relative, from the containing package.json - files: ['build/test/dom/cases/keyboard/**/*.spec.mjs'] + files: ['build/test/dom/cases/keyboard/**/*.tests.mjs'] }, { name: 'engine/keyboard-storage', // Relative, from the containing package.json - files: ['build/test/dom/cases/keyboard-storage/**/*.spec.mjs'] + files: ['build/test/dom/cases/keyboard-storage/**/*.tests.mjs'] }, { name: 'engine/osk', // Relative, from the containing package.json - files: ['build/test/dom/cases/osk/**/*.spec.mjs'] + files: ['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.js b/web/src/test/auto/headless/engine/keyboard/keyboard-loading.tests.js similarity index 100% rename from web/src/test/auto/headless/engine/keyboard/keyboard-loading.js rename to web/src/test/auto/headless/engine/keyboard/keyboard-loading.tests.js 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 1637ea82d60..8d937f55afd 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: [ - 'build/test/integrated//**/*.spec.mjs', - // '**/*.spec.html' + 'build/test/integrated//**/*.tests.mjs', + // '**/*.tests.html' ], middleware: [ // Rewrites short-hand paths for test resources, making them fully relative to the repo root. From 718881a027eea8479b94d4376196eeca9b884ea8 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Tue, 26 Nov 2024 17:46:59 +0100 Subject: [PATCH 047/117] chore(core): rename test files This change rename the test files for Core according to the discussion at the Keyman conference in November 2024. --- .../{action_api.cpp => action_api.tests.cpp} | 0 ...n_set_api.cpp => action_set_api.tests.cpp} | 0 ..._get_api.cpp => actions_get_api.tests.cpp} | 0 ...malize.cpp => actions_normalize.tests.cpp} | 0 ...{context_api.cpp => context_api.tests.cpp} | 0 .../{debug_api.cpp => debug_api.tests.cpp} | 0 ...eyboard_api.cpp => keyboard_api.tests.cpp} | 0 ..._kmx_context.cpp => kmx_context.tests.cpp} | 0 ..._kmx_xstring.cpp => kmx_xstring.tests.cpp} | 0 core/tests/unit/kmnkbd/meson.build | 24 ++++++++--------- ...{options_api.cpp => options_api.tests.cpp} | 0 .../{state_api.cpp => state_api.tests.cpp} | 0 ...xt_api.cpp => state_context_api.tests.cpp} | 0 ...event.cpp => kmx_external_event.tests.cpp} | 0 .../kmx/{kmx_imx.cpp => kmx_imx.tests.cpp} | 0 ...mx_key_list.cpp => kmx_key_list.tests.cpp} | 0 core/tests/unit/kmx/meson.build | 6 ++--- ...on.cpp => context_normalization.tests.cpp} | 0 ...e_ldml_min.cpp => core_ldml_min.tests.cpp} | 0 .../{test_kmx_plus.cpp => kmx_plus.tests.cpp} | 0 core/tests/unit/ldml/meson.build | 26 +++++++++---------- ...st_transforms.cpp => transforms.tests.cpp} | 0 .../{test_unicode.cpp => unicode.tests.cpp} | 0 core/tests/unit/utftest/meson.build | 2 +- .../{utftest.cpp => utftest.tests.cpp} | 0 25 files changed, 29 insertions(+), 29 deletions(-) rename core/tests/unit/kmnkbd/{action_api.cpp => action_api.tests.cpp} (100%) rename core/tests/unit/kmnkbd/{action_set_api.cpp => action_set_api.tests.cpp} (100%) rename core/tests/unit/kmnkbd/{test_actions_get_api.cpp => actions_get_api.tests.cpp} (100%) rename core/tests/unit/kmnkbd/{test_actions_normalize.cpp => actions_normalize.tests.cpp} (100%) rename core/tests/unit/kmnkbd/{context_api.cpp => context_api.tests.cpp} (100%) rename core/tests/unit/kmnkbd/{debug_api.cpp => debug_api.tests.cpp} (100%) rename core/tests/unit/kmnkbd/{keyboard_api.cpp => keyboard_api.tests.cpp} (100%) rename core/tests/unit/kmnkbd/{test_kmx_context.cpp => kmx_context.tests.cpp} (100%) rename core/tests/unit/kmnkbd/{test_kmx_xstring.cpp => kmx_xstring.tests.cpp} (100%) rename core/tests/unit/kmnkbd/{options_api.cpp => options_api.tests.cpp} (100%) rename core/tests/unit/kmnkbd/{state_api.cpp => state_api.tests.cpp} (100%) rename core/tests/unit/kmnkbd/{state_context_api.cpp => state_context_api.tests.cpp} (100%) rename core/tests/unit/kmx/{kmx_external_event.cpp => kmx_external_event.tests.cpp} (100%) rename core/tests/unit/kmx/{kmx_imx.cpp => kmx_imx.tests.cpp} (100%) rename core/tests/unit/kmx/{kmx_key_list.cpp => kmx_key_list.tests.cpp} (100%) rename core/tests/unit/ldml/{test_context_normalization.cpp => context_normalization.tests.cpp} (100%) rename core/tests/unit/ldml/{core_ldml_min.cpp => core_ldml_min.tests.cpp} (100%) rename core/tests/unit/ldml/{test_kmx_plus.cpp => kmx_plus.tests.cpp} (100%) rename core/tests/unit/ldml/{test_transforms.cpp => transforms.tests.cpp} (100%) rename core/tests/unit/ldml/{test_unicode.cpp => unicode.tests.cpp} (100%) rename core/tests/unit/utftest/{utftest.cpp => utftest.tests.cpp} (100%) diff --git a/core/tests/unit/kmnkbd/action_api.cpp b/core/tests/unit/kmnkbd/action_api.tests.cpp similarity index 100% rename from core/tests/unit/kmnkbd/action_api.cpp rename to core/tests/unit/kmnkbd/action_api.tests.cpp diff --git a/core/tests/unit/kmnkbd/action_set_api.cpp b/core/tests/unit/kmnkbd/action_set_api.tests.cpp similarity index 100% rename from core/tests/unit/kmnkbd/action_set_api.cpp rename to core/tests/unit/kmnkbd/action_set_api.tests.cpp diff --git a/core/tests/unit/kmnkbd/test_actions_get_api.cpp b/core/tests/unit/kmnkbd/actions_get_api.tests.cpp similarity index 100% rename from core/tests/unit/kmnkbd/test_actions_get_api.cpp rename to core/tests/unit/kmnkbd/actions_get_api.tests.cpp diff --git a/core/tests/unit/kmnkbd/test_actions_normalize.cpp b/core/tests/unit/kmnkbd/actions_normalize.tests.cpp similarity index 100% rename from core/tests/unit/kmnkbd/test_actions_normalize.cpp rename to core/tests/unit/kmnkbd/actions_normalize.tests.cpp 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 100% rename from core/tests/unit/kmnkbd/debug_api.cpp rename to core/tests/unit/kmnkbd/debug_api.tests.cpp 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 100% rename from core/tests/unit/kmnkbd/test_kmx_context.cpp rename to core/tests/unit/kmnkbd/kmx_context.tests.cpp diff --git a/core/tests/unit/kmnkbd/test_kmx_xstring.cpp b/core/tests/unit/kmnkbd/kmx_xstring.tests.cpp similarity index 100% rename from core/tests/unit/kmnkbd/test_kmx_xstring.cpp rename to core/tests/unit/kmnkbd/kmx_xstring.tests.cpp 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 100% rename from core/tests/unit/kmnkbd/state_api.cpp rename to core/tests/unit/kmnkbd/state_api.tests.cpp diff --git a/core/tests/unit/kmnkbd/state_context_api.cpp b/core/tests/unit/kmnkbd/state_context_api.tests.cpp similarity index 100% rename from core/tests/unit/kmnkbd/state_context_api.cpp rename to core/tests/unit/kmnkbd/state_context_api.tests.cpp diff --git a/core/tests/unit/kmx/kmx_external_event.cpp b/core/tests/unit/kmx/kmx_external_event.tests.cpp similarity index 100% rename from core/tests/unit/kmx/kmx_external_event.cpp rename to core/tests/unit/kmx/kmx_external_event.tests.cpp diff --git a/core/tests/unit/kmx/kmx_imx.cpp b/core/tests/unit/kmx/kmx_imx.tests.cpp similarity index 100% rename from core/tests/unit/kmx/kmx_imx.cpp rename to core/tests/unit/kmx/kmx_imx.tests.cpp diff --git a/core/tests/unit/kmx/kmx_key_list.cpp b/core/tests/unit/kmx/kmx_key_list.tests.cpp similarity index 100% rename from core/tests/unit/kmx/kmx_key_list.cpp rename to core/tests/unit/kmx/kmx_key_list.tests.cpp 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 100% rename from core/tests/unit/ldml/test_context_normalization.cpp rename to core/tests/unit/ldml/context_normalization.tests.cpp diff --git a/core/tests/unit/ldml/core_ldml_min.cpp b/core/tests/unit/ldml/core_ldml_min.tests.cpp similarity index 100% rename from core/tests/unit/ldml/core_ldml_min.cpp rename to core/tests/unit/ldml/core_ldml_min.tests.cpp diff --git a/core/tests/unit/ldml/test_kmx_plus.cpp b/core/tests/unit/ldml/kmx_plus.tests.cpp similarity index 100% rename from core/tests/unit/ldml/test_kmx_plus.cpp rename to core/tests/unit/ldml/kmx_plus.tests.cpp diff --git a/core/tests/unit/ldml/meson.build b/core/tests/unit/ldml/meson.build index 20ad621b506..f46b08b4b3f 100644 --- a/core/tests/unit/ldml/meson.build +++ b/core/tests/unit/ldml/meson.build @@ -82,8 +82,8 @@ ldml = executable('ldml', objects: lib.extract_all_objects(recursive: false), ) -core_ldml_min = executable('core_ldml_min', - ['core_ldml_min.cpp'], +core_ldml_min = executable('core_ldml_min_tests', + ['core_ldml_min.tests.cpp'], cpp_args: defns + warns, include_directories: [inc, libsrc], link_args: links, @@ -91,12 +91,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, @@ -104,18 +104,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 @@ -125,19 +125,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, @@ -146,7 +146,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 100% rename from core/tests/unit/ldml/test_transforms.cpp rename to core/tests/unit/ldml/transforms.tests.cpp diff --git a/core/tests/unit/ldml/test_unicode.cpp b/core/tests/unit/ldml/unicode.tests.cpp similarity index 100% rename from core/tests/unit/ldml/test_unicode.cpp rename to core/tests/unit/ldml/unicode.tests.cpp diff --git a/core/tests/unit/utftest/meson.build b/core/tests/unit/utftest/meson.build index 4ab6cb74ca0..c82b6f98c55 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: [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 From 9f938d1b27054615ba84d3feacc84993a01f1e6d Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Tue, 26 Nov 2024 13:01:27 -0500 Subject: [PATCH 048/117] auto: increment master version to 18.0.146 --- HISTORY.md | 5 +++++ VERSION.md | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index aafdade9281..282950db67e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,10 @@ # Keyman Version History +## 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) diff --git a/VERSION.md b/VERSION.md index e917147038f..aa8a5efd517 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.145 \ No newline at end of file +18.0.146 \ No newline at end of file From 4a852c9522b60becca122856372a08b0352b732c Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Tue, 26 Nov 2024 17:56:04 +0100 Subject: [PATCH 049/117] chore(linux): rename test files This change rename the test files for Linux according to the discussion at the Keyman conference in November 2024. Python is pretty opinionated about the naming of files, so we have to use `*_tests.py` as test filename instead of the usual `*.tests.py`. --- linux/.gitignore | 2 +- .../test/{bcp47util_tests.c => bcp47util.tests.c} | 0 .../test/{keymanutil_tests.c => keymanutil.tests.c} | 0 linux/ibus-keyman/src/test/meson.build | 4 ++-- linux/keyman-config/run-tests.sh | 12 ++++++------ .../tests/{test_bcp47tag.py => bcp47tag_tests.py} | 0 ...ils.py => canonical_language_code_utils_tests.py} | 0 ...custom_keyboards.py => custom_keyboards_tests.py} | 0 .../{test_dconf_util.py => dconf_util_tests.py} | 0 .../tests/{test_get_kmp.py => get_kmp_tests.py} | 0 ...yboards_util.py => gnome_keyboards_util_tests.py} | 0 .../tests/{test_gsettings.py => gsettings_tests.py} | 0 ...est_handle_install.py => handle_install_tests.py} | 0 .../tests/{test_ibus_util.py => ibus_util_tests.py} | 0 .../{test_install_kmp.py => install_kmp_tests.py} | 0 .../tests/{test_kvk2ldml.py => kvk2ldml_tests.py} | 0 ...{test_lang_tags_map.py => lang_tags_map_tests.py} | 0 ...letion.py => package_install_completion_tests.py} | 0 ...{test_uninstall_kmp.py => uninstall_kmp_tests.py} | 0 19 files changed, 9 insertions(+), 9 deletions(-) rename linux/ibus-keyman/src/test/{bcp47util_tests.c => bcp47util.tests.c} (100%) rename linux/ibus-keyman/src/test/{keymanutil_tests.c => keymanutil.tests.c} (100%) rename linux/keyman-config/tests/{test_bcp47tag.py => bcp47tag_tests.py} (100%) rename linux/keyman-config/tests/{test_canonical_language_code_utils.py => canonical_language_code_utils_tests.py} (100%) rename linux/keyman-config/tests/{test_custom_keyboards.py => custom_keyboards_tests.py} (100%) rename linux/keyman-config/tests/{test_dconf_util.py => dconf_util_tests.py} (100%) rename linux/keyman-config/tests/{test_get_kmp.py => get_kmp_tests.py} (100%) rename linux/keyman-config/tests/{test_gnome_keyboards_util.py => gnome_keyboards_util_tests.py} (100%) rename linux/keyman-config/tests/{test_gsettings.py => gsettings_tests.py} (100%) rename linux/keyman-config/tests/{test_handle_install.py => handle_install_tests.py} (100%) rename linux/keyman-config/tests/{test_ibus_util.py => ibus_util_tests.py} (100%) rename linux/keyman-config/tests/{test_install_kmp.py => install_kmp_tests.py} (100%) rename linux/keyman-config/tests/{test_kvk2ldml.py => kvk2ldml_tests.py} (100%) rename linux/keyman-config/tests/{test_lang_tags_map.py => lang_tags_map_tests.py} (100%) rename linux/keyman-config/tests/{test_package_install_completion.py => package_install_completion_tests.py} (100%) rename linux/keyman-config/tests/{test_uninstall_kmp.py => uninstall_kmp_tests.py} (100%) 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/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/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 From f641b3cc086206e9fa164f344eb465edcf8396df Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Wed, 27 Nov 2024 01:27:59 +0000 Subject: [PATCH 050/117] chore(developer): remove unnecessary assignment to sFlag block variable --- developer/src/kmcmplib/src/Compiler.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/developer/src/kmcmplib/src/Compiler.cpp b/developer/src/kmcmplib/src/Compiler.cpp index c3164c4c367..ff4ab560a52 100644 --- a/developer/src/kmcmplib/src/Compiler.cpp +++ b/developer/src/kmcmplib/src/Compiler.cpp @@ -2562,8 +2562,6 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX //printf("--EXTENDEDEND--\n"); p = q + 1; - - sFlag = 0; } continue; From a5c80243e742746dbc29995464959ef3982b926d Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Wed, 27 Nov 2024 02:24:11 +0000 Subject: [PATCH 051/117] chore(developer): add six test cases for ListIndex --- .../test/ldml-keyboard/test-string-list.ts | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/common/web/types/test/ldml-keyboard/test-string-list.ts b/common/web/types/test/ldml-keyboard/test-string-list.ts index 0f73bbf93fd..9188f3b440a 100644 --- a/common/web/types/test/ldml-keyboard/test-string-list.ts +++ b/common/web/types/test/ldml-keyboard/test-string-list.ts @@ -1,9 +1,48 @@ import 'mocha'; import { assert } from 'chai'; -//import { ListIndex, ListItem } from '../../src/ldml-keyboard/string-list.js'; -import { ListItem } from '../../src/ldml-keyboard/string-list.js'; +import { StrsItem } from '../../src/kmx/kmx-plus/kmx-plus.js'; +import { ListIndex, ListItem } from '../../src/ldml-keyboard/string-list.js'; describe('Test of String-List', () => { + describe('should 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 strsItemOne = new StrsItem("abc"); + const strsItemTwo = new StrsItem("abc"); + const listItemOne = new ListIndex(strsItemOne); + const listItemTwo = new ListIndex(strsItemTwo); + assert.isTrue(listItemOne.isEqual(listItemTwo)); + }); + it('can check two different ListIndex are not equal', () => { + const strsItemOne = new StrsItem("abc"); + const strsItemTwo = new StrsItem("def"); + const listItemOne = new ListIndex(strsItemOne); + const listItemTwo = new ListIndex(strsItemTwo); + assert.isFalse(listItemOne.isEqual(listItemTwo)); + }); + it('can check a ListIndex and string for equality', () => { + const strsItem = new StrsItem("abc"); + const listItem = new ListIndex(strsItem); + const aString = "abc"; + assert.isTrue(listItem.isEqual(aString)); + }); + it('can check a ListIndex and string for inequality', () => { + const strsItem = new StrsItem("abc"); + const listItem = new ListIndex(strsItem); + 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('should test ListItem', () => { it('fromStrings returns an empty ListItem if source is null', () => { const actual = ListItem.fromStrings(null, null, null); From b10634eb978e7211a1e470cd880ca5d1c003e937 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 27 Nov 2024 09:46:09 +0700 Subject: [PATCH 052/117] refactor(common): move all lexical model types into `LexicalModelTypes` container Many of the types had very generic names (e.g. `Configuration`), and as the types are now exported from `@keymanapp/common-types`, this was unhelpful. For units with many references, I used TypeScript's import-equals to reduce the change impact. For units with only a few references, I added the `LexicalModelTypes.` prefix to the references in source. (Best reference I could find for import-equals: https://github.com/evanw/esbuild/commit/b722fa4e49174d474cd5d6900fe0a1678ba7bcb4) Fixes: #12516 --- common/web/types/src/main.ts | 2 +- .../kmc-model/src/join-word-breaker-decorator.ts | 4 +++- developer/src/kmc-model/src/lexical-model.ts | 5 ++++- developer/src/kmc-model/src/model-defaults.ts | 4 +++- developer/src/kmc-model/src/model-definitions.ts | 4 +++- .../kmc-model/src/script-overrides-decorator.ts | 4 +++- web/src/app/webview/src/configuration.ts | 4 ++-- web/src/app/webview/src/contextManager.ts | 4 ++-- .../prediction/languageProcessor.interface.ts | 12 ++++++------ .../src/prediction/predictionContext.ts | 5 ++++- web/src/engine/js-processor/src/outputTarget.ts | 10 +++++----- web/src/engine/js-processor/src/ruleBehavior.ts | 4 ++-- .../engine/main/src/headless/contextWindow.ts | 10 +++++----- .../engine/main/src/headless/inputProcessor.ts | 4 ++-- .../main/src/headless/languageProcessor.ts | 6 +++++- .../engine/osk/src/banner/suggestionBanner.ts | 14 +++++++------- .../predictive-text/templates/src/common.ts | 8 +++++++- .../templates/src/quote-behavior.ts | 4 ++-- .../templates/src/tokenization.ts | 10 +++++----- .../predictive-text/templates/src/trie-model.ts | 16 +++++++++++++++- .../engine/predictive-text/types/message.d.ts | 6 +++++- .../wordbreakers/src/main/ascii.ts | 8 ++++---- .../wordbreakers/src/main/default/index.ts | 6 +++--- .../wordbreakers/src/main/placeholder.ts | 4 ++-- .../predictive-text/worker-main/src/lmlayer.ts | 10 +++++++++- .../src/main/correction/context-tracker.ts | 8 +++++++- .../src/main/correction/distance-modeler.ts | 8 +++++++- .../main/correction/transform-tokenization.ts | 5 ++++- .../worker-thread/src/main/index.ts | 4 +++- .../worker-thread/src/main/model-compositor.ts | 11 ++++++++++- .../worker-thread/src/main/model-helpers.ts | 6 +++++- .../worker-thread/src/main/models/dummy-model.ts | 13 ++++++++++++- .../worker-thread/src/main/predict-helpers.ts | 12 +++++++++++- .../worker-thread/src/main/transformUtils.ts | 8 ++++---- .../worker-thread/src/main/worker-interfaces.ts | 9 ++++++++- 35 files changed, 180 insertions(+), 72 deletions(-) diff --git a/common/web/types/src/main.ts b/common/web/types/src/main.ts index c3b24c5123d..8dd65002998 100644 --- a/common/web/types/src/main.ts +++ b/common/web/types/src/main.ts @@ -30,6 +30,6 @@ export { UnicodeSetParser, UnicodeSet } from './ldml-keyboard/unicodeset-parser- export { VariableParser, MarkerParser } from './ldml-keyboard/pattern-parser.js'; export { ElementString } from './kmx/kmx-plus/element-string.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/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/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/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 d08774850ff..c13a0bf00ad 100644 --- a/web/src/engine/main/src/headless/inputProcessor.ts +++ b/web/src/engine/main/src/headless/inputProcessor.ts @@ -19,7 +19,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 = { @@ -355,7 +355,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/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/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/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/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-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'; From e8bc0773dfdec83a00641dd57bf6735847ce39c5 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 27 Nov 2024 10:03:13 +0700 Subject: [PATCH 053/117] refactor(common): LexicalModelTypes tests Fixes: #12516 --- .../types/test/lexical-model-types.tests.ts | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/common/web/types/test/lexical-model-types.tests.ts b/common/web/types/test/lexical-model-types.tests.ts index 8944342ed6e..da4c4fd8ef2 100644 --- a/common/web/types/test/lexical-model-types.tests.ts +++ b/common/web/types/test/lexical-model-types.tests.ts @@ -5,19 +5,19 @@ * 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'; +import { KMXPlus, ElementString, LexicalModelTypes } 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; +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 From dc2b9b2ad945e8fcf361a3d91b9bc1f04fed5412 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 27 Nov 2024 10:13:09 +0700 Subject: [PATCH 054/117] refactor(developer): LexicalModelTypes tests --- .../test/test-compile-model-with-pseudoclosure.ts | 8 ++++---- developer/src/kmc-model/test/test-compile-trie.ts | 4 ++-- .../kmc-model/test/test-default-search-term-to-key.ts | 10 +++++----- developer/src/kmc-model/test/test-join-word-breaker.ts | 4 ++-- developer/src/kmc-model/test/test-model-definitions.ts | 6 +++--- .../kmc-model/test/test-override-script-defaults.ts | 4 ++-- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/developer/src/kmc-model/test/test-compile-model-with-pseudoclosure.ts b/developer/src/kmc-model/test/test-compile-model-with-pseudoclosure.ts index 049776ec201..b243b51f9c8 100644 --- a/developer/src/kmc-model/test/test-compile-model-with-pseudoclosure.ts +++ b/developer/src/kmc-model/test/test-compile-model-with-pseudoclosure.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-trie.ts b/developer/src/kmc-model/test/test-compile-trie.ts index 845022cef5c..d36df694f43 100644 --- a/developer/src/kmc-model/test/test-compile-trie.ts +++ b/developer/src/kmc-model/test/test-compile-trie.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-search-term-to-key.ts b/developer/src/kmc-model/test/test-default-search-term-to-key.ts index 0f8120e6bae..48cf2ef1f5a 100644 --- a/developer/src/kmc-model/test/test-default-search-term-to-key.ts +++ b/developer/src/kmc-model/test/test-default-search-term-to-key.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/test-join-word-breaker.ts index ff220088f5c..e40d2ccdc0d 100644 --- a/developer/src/kmc-model/test/test-join-word-breaker.ts +++ b/developer/src/kmc-model/test/test-join-word-breaker.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-model-definitions.ts b/developer/src/kmc-model/test/test-model-definitions.ts index ee569a01b1a..4eaccfb792c 100644 --- a/developer/src/kmc-model/test/test-model-definitions.ts +++ b/developer/src/kmc-model/test/test-model-definitions.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/test-override-script-defaults.ts index b8afb18900b..5c325e4da16 100644 --- a/developer/src/kmc-model/test/test-override-script-defaults.ts +++ b/developer/src/kmc-model/test/test-override-script-defaults.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; } }); From ef46a8eab19f19591b68e49b26374ce943faea11 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Wed, 27 Nov 2024 03:28:36 +0000 Subject: [PATCH 055/117] chore(developer): add a ListItem.fromStrings() test case --- .../test/ldml-keyboard/test-string-list.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/common/web/types/test/ldml-keyboard/test-string-list.ts b/common/web/types/test/ldml-keyboard/test-string-list.ts index 9188f3b440a..66e724e148f 100644 --- a/common/web/types/test/ldml-keyboard/test-string-list.ts +++ b/common/web/types/test/ldml-keyboard/test-string-list.ts @@ -1,6 +1,6 @@ import 'mocha'; import { assert } from 'chai'; -import { StrsItem } from '../../src/kmx/kmx-plus/kmx-plus.js'; +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', () => { @@ -44,10 +44,23 @@ describe('Test of String-List', () => { }); }); describe('should test ListItem', () => { - it('fromStrings returns an empty ListItem if source is null', () => { + it('fromStrings 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('fromStrings 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 = new ListItem(); + expected.push(new ListIndex(new StrsItem("abc"))); + assert.deepEqual(actual, expected); + }); }); }); + +function stubSectionsStrsAllocString(s?: string, opts?: StrsOptions, sections?: DependencySections): StrsItem { + return new StrsItem(s); +} From 15c71d7b951fe62ee21a4e31e32e79d6bd6807c9 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Wed, 27 Nov 2024 03:38:24 +0000 Subject: [PATCH 056/117] chore(developer): add a further ListItem.fromStrings() test case --- .../web/types/test/ldml-keyboard/test-string-list.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/common/web/types/test/ldml-keyboard/test-string-list.ts b/common/web/types/test/ldml-keyboard/test-string-list.ts index 66e724e148f..cfb09322e3b 100644 --- a/common/web/types/test/ldml-keyboard/test-string-list.ts +++ b/common/web/types/test/ldml-keyboard/test-string-list.ts @@ -58,6 +58,16 @@ describe('Test of String-List', () => { expected.push(new ListIndex(new StrsItem("abc"))); assert.deepEqual(actual, expected); }); + it('fromStrings 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 = new ListItem(); + for (const s of source) + expected.push(new ListIndex(new StrsItem(s))); + assert.deepEqual(actual, expected); + }); }); }); From 88b0f712d09adb86e60d85229aa3480f3b3c7d38 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Wed, 27 Nov 2024 03:47:28 +0000 Subject: [PATCH 057/117] chore(developer): add three ListItem.getItemOrder() test cases --- .../test/ldml-keyboard/test-string-list.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/common/web/types/test/ldml-keyboard/test-string-list.ts b/common/web/types/test/ldml-keyboard/test-string-list.ts index cfb09322e3b..f593bae9fe0 100644 --- a/common/web/types/test/ldml-keyboard/test-string-list.ts +++ b/common/web/types/test/ldml-keyboard/test-string-list.ts @@ -68,6 +68,27 @@ describe('Test of String-List', () => { expected.push(new ListIndex(new StrsItem(s))); assert.deepEqual(actual, expected); }); + it('getItemOrder should return a valid index for the first item', () => { + const listItem = new ListItem(); + for (const s of ["abc", "def", "ghi"]) + listItem.push(new ListIndex(new StrsItem(s))); + const index = listItem.getItemOrder("abc"); + assert.equal(index, 0); + }); + it('getItemOrder should return a valid index for a later item', () => { + const listItem = new ListItem(); + for (const s of ["abc", "def", "ghi"]) + listItem.push(new ListIndex(new StrsItem(s))); + const index = listItem.getItemOrder("ghi"); + assert.equal(index, 2); + }); + it('getItemOrder should return -1 for a missing item', () => { + const listItem = new ListItem(); + for (const s of ["abc", "def", "ghi"]) + listItem.push(new ListIndex(new StrsItem(s))); + const index = listItem.getItemOrder("jkl"); + assert.equal(index, -1); + }); }); }); From b54b0058300314006b6395e913bb5488092b0b98 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 27 Nov 2024 11:52:53 +0700 Subject: [PATCH 058/117] refactor(common): move remaining LDML keyboard types into `LdmlKeyboardTypes` Follows: #12712 --- common/web/types/src/main-ldml-keyboard.ts | 8 ++++++ common/web/types/src/main.ts | 5 +--- .../types/test/lexical-model-types.tests.ts | 4 +-- .../types/kmx/kmx-plus-builder/build-elem.ts | 8 +++--- .../src/kmc-kmn/src/compiler/compiler.ts | 8 +++--- .../src/kmc-ldml/src/compiler/compiler.ts | 6 ++-- .../kmc-ldml/src/compiler/empty-compiler.ts | 6 ++-- .../kmc-ldml/src/compiler/linter-keycaps.ts | 4 +-- .../src/compiler/substitution-tracker.ts | 10 +++---- developer/src/kmc-ldml/src/compiler/tran.ts | 12 ++++---- developer/src/kmc-ldml/src/compiler/vars.ts | 28 +++++++++---------- developer/src/kmc-ldml/test/helpers/index.ts | 4 +-- developer/src/kmc-ldml/test/test-keys.ts | 8 +++--- developer/src/kmc-ldml/test/test-tran.ts | 10 +++---- 14 files changed, 63 insertions(+), 58 deletions(-) create mode 100644 common/web/types/src/main-ldml-keyboard.ts 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 8dd65002998..071c931e9e9 100644 --- a/common/web/types/src/main.ts +++ b/common/web/types/src/main.ts @@ -25,10 +25,7 @@ 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 * as LexicalModelTypes from './lexical-model-types.js'; diff --git a/common/web/types/test/lexical-model-types.tests.ts b/common/web/types/test/lexical-model-types.tests.ts index da4c4fd8ef2..ef8bed28a50 100644 --- a/common/web/types/test/lexical-model-types.tests.ts +++ b/common/web/types/test/lexical-model-types.tests.ts @@ -5,7 +5,7 @@ * imported and compiled without any compiler errors. */ -import { KMXPlus, ElementString, LexicalModelTypes } from "@keymanapp/common-types"; +import { KMXPlus, LdmlKeyboardTypes, LexicalModelTypes } from "@keymanapp/common-types"; export let u: LexicalModelTypes.USVString; export let l: LexicalModelTypes.Transform; @@ -21,5 +21,5 @@ export let lmp: LexicalModelTypes.LexicalModelPunctuation; // try some of the other types - that should still work -export let elemString: ElementString; +export let elemString: LdmlKeyboardTypes.ElementString; export let section: KMXPlus.Section; 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/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-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..aaba0950260 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,7 +35,7 @@ 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()) { // replace all \\uXXXX with the actual code point. // this lets us analyze whether there are PUA, unassigned, etc. @@ -47,7 +47,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/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/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/test-keys.ts index 8c0a47bebb3..b639c194cc3 100644 --- a/developer/src/kmc-ldml/test/test-keys.ts +++ b/developer/src/kmc-ldml/test/test-keys.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-tran.ts b/developer/src/kmc-ldml/test/test-tran.ts index 0099c1f1029..2fc401e66b6 100644 --- a/developer/src/kmc-ldml/test/test-tran.ts +++ b/developer/src/kmc-ldml/test/test-tran.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}`); }, From 769259e6f6a78bc7763ce7d233b42ab2181988c2 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Wed, 27 Nov 2024 05:04:20 +0000 Subject: [PATCH 059/117] chore(developer): add four test cases for ListItem.isEqual, plus refactor for length --- .../test/ldml-keyboard/test-string-list.ts | 66 +++++++++++-------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/common/web/types/test/ldml-keyboard/test-string-list.ts b/common/web/types/test/ldml-keyboard/test-string-list.ts index f593bae9fe0..c638f0043eb 100644 --- a/common/web/types/test/ldml-keyboard/test-string-list.ts +++ b/common/web/types/test/ldml-keyboard/test-string-list.ts @@ -11,28 +11,22 @@ describe('Test of String-List', () => { assert.deepEqual(actual.value, strsItem); }); it('can check two ListIndex for equality', () => { - const strsItemOne = new StrsItem("abc"); - const strsItemTwo = new StrsItem("abc"); - const listItemOne = new ListIndex(strsItemOne); - const listItemTwo = new ListIndex(strsItemTwo); + 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 strsItemOne = new StrsItem("abc"); - const strsItemTwo = new StrsItem("def"); - const listItemOne = new ListIndex(strsItemOne); - const listItemTwo = new ListIndex(strsItemTwo); + 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 strsItem = new StrsItem("abc"); - const listItem = new ListIndex(strsItem); + 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 strsItem = new StrsItem("abc"); - const listItem = new ListIndex(strsItem); + const listItem = new ListIndex(new StrsItem("abc")); const aString = "def"; assert.isFalse(listItem.isEqual(aString)); }); @@ -54,8 +48,7 @@ describe('Test of String-List', () => { const sections = { strs: new Strs }; sections.strs.allocString = stubSectionsStrsAllocString; const actual = ListItem.fromStrings(source, null, sections); - const expected = new ListItem(); - expected.push(new ListIndex(new StrsItem("abc"))); + const expected = initListItem(source); assert.deepEqual(actual, expected); }); it('fromStrings should return a valid ListItem from a longer source', () => { @@ -63,35 +56,54 @@ describe('Test of String-List', () => { const sections = { strs: new Strs }; sections.strs.allocString = stubSectionsStrsAllocString; const actual = ListItem.fromStrings(source, null, sections); - const expected = new ListItem(); - for (const s of source) - expected.push(new ListIndex(new StrsItem(s))); + const expected = initListItem(source); assert.deepEqual(actual, expected); }); it('getItemOrder should return a valid index for the first item', () => { - const listItem = new ListItem(); - for (const s of ["abc", "def", "ghi"]) - listItem.push(new ListIndex(new StrsItem(s))); + const listItem = initListItem(["abc", "def", "ghi"]); const index = listItem.getItemOrder("abc"); assert.equal(index, 0); }); it('getItemOrder should return a valid index for a later item', () => { - const listItem = new ListItem(); - for (const s of ["abc", "def", "ghi"]) - listItem.push(new ListIndex(new StrsItem(s))); + const listItem = initListItem(["abc", "def", "ghi"]); const index = listItem.getItemOrder("ghi"); assert.equal(index, 2); }); it('getItemOrder should return -1 for a missing item', () => { - const listItem = new ListItem(); - for (const s of ["abc", "def", "ghi"]) - listItem.push(new ListIndex(new StrsItem(s))); - const index = listItem.getItemOrder("jkl"); + const listItem = initListItem(["abc", "def", "ghi"]); + const index = listItem.getItemOrder("jkl"); assert.equal(index, -1); }); + it('isEqual should return true for two empty ListItems', () => { + const listItemOne = new ListItem(); + const listItemTwo = new ListItem(); + assert.isTrue(listItemOne.isEqual(listItemTwo)); + }); + it('isEqual should return false for empty and non-empty ListItems', () => { + const listItemOne = new ListItem(); + const listItemTwo = initListItem(["abc"]); + assert.isFalse(listItemOne.isEqual(listItemTwo)); + }); + it('isEqual should return true for identical ListItems', () => { + const listItemOne = initListItem(["abc", "def", "ghi"]); + const listItemTwo = initListItem(["abc", "def", "ghi"]); + assert.isTrue(listItemOne.isEqual(listItemTwo)); + }); + it('isEqual should return false for different length ListItems', () => { + const listItemOne = initListItem(["abc", "def"]); + const listItemTwo = initListItem(["abc", "def", "ghi"]); + assert.isFalse(listItemOne.isEqual(listItemTwo)); + }); }); }); 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; +} From d77c5aeb6bc6c94f22d94f64536ef8846b879553 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Wed, 27 Nov 2024 05:16:24 +0000 Subject: [PATCH 060/117] chore(developer): add seven additional test cases for ListItem.isEqual --- .../test/ldml-keyboard/test-string-list.ts | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/common/web/types/test/ldml-keyboard/test-string-list.ts b/common/web/types/test/ldml-keyboard/test-string-list.ts index c638f0043eb..ce207129216 100644 --- a/common/web/types/test/ldml-keyboard/test-string-list.ts +++ b/common/web/types/test/ldml-keyboard/test-string-list.ts @@ -84,6 +84,11 @@ describe('Test of String-List', () => { const listItemTwo = initListItem(["abc"]); assert.isFalse(listItemOne.isEqual(listItemTwo)); }); + it('isEqual should return false for non-empty and empty ListItems', () => { + const listItemOne = initListItem(["abc"]); + const listItemTwo = new ListItem(); + assert.isFalse(listItemOne.isEqual(listItemTwo)); + }); it('isEqual should return true for identical ListItems', () => { const listItemOne = initListItem(["abc", "def", "ghi"]); const listItemTwo = initListItem(["abc", "def", "ghi"]); @@ -95,6 +100,26 @@ describe('Test of String-List', () => { assert.isFalse(listItemOne.isEqual(listItemTwo)); }); }); + it('isEqual should return true for empty ListItem and string[]', () => { + const listItem = new ListItem(); + assert.isTrue(listItem.isEqual([])); + }); + it('isEqual should return false for empty ListItem and non-empty string[]', () => { + const listItem = new ListItem(); + assert.isFalse(listItem.isEqual(["abc"])); + }); + it('isEqual should return false for non-empty ListItem and empty string[]', () => { + const listItem = initListItem(["abc"]);; + assert.isFalse(listItem.isEqual([])); + }); + it('isEqual should return true for identical ListItem and string[]', () => { + const listItem = initListItem(["abc", "def", "ghi"]); + assert.isTrue(listItem.isEqual(["abc", "def", "ghi"])); + }); + it('isEqual should return false for different length ListItem and string[]', () => { + const listItem = initListItem(["abc", "def"]); + assert.isFalse(listItem.isEqual(["abc", "def", "ghi"])); + }); }); function stubSectionsStrsAllocString(s?: string, opts?: StrsOptions, sections?: DependencySections): StrsItem { From 04a8a0a5d5486ba3803fcb7b266f5fcc7aa9428b Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Wed, 27 Nov 2024 05:33:07 +0000 Subject: [PATCH 061/117] chore(developer): add seven test cases for ListItem.compareTo --- .../test/ldml-keyboard/test-string-list.ts | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/common/web/types/test/ldml-keyboard/test-string-list.ts b/common/web/types/test/ldml-keyboard/test-string-list.ts index ce207129216..3a74678a32a 100644 --- a/common/web/types/test/ldml-keyboard/test-string-list.ts +++ b/common/web/types/test/ldml-keyboard/test-string-list.ts @@ -120,6 +120,41 @@ describe('Test of String-List', () => { const listItem = initListItem(["abc", "def"]); assert.isFalse(listItem.isEqual(["abc", "def", "ghi"])); }); + it('compareTo 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('compareTo 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('compareTo 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('compareTo 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('compareTo 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('compareTo 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('compareTo 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); + }); }); function stubSectionsStrsAllocString(s?: string, opts?: StrsOptions, sections?: DependencySections): StrsItem { From b3398fb9418692c3b4d092679825d0fb807e1d59 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Wed, 27 Nov 2024 05:39:56 +0000 Subject: [PATCH 062/117] chore(developer): add test cases for ListItem.toString() and toStringArray() --- common/web/types/test/ldml-keyboard/test-string-list.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/common/web/types/test/ldml-keyboard/test-string-list.ts b/common/web/types/test/ldml-keyboard/test-string-list.ts index 3a74678a32a..ba200413298 100644 --- a/common/web/types/test/ldml-keyboard/test-string-list.ts +++ b/common/web/types/test/ldml-keyboard/test-string-list.ts @@ -155,6 +155,15 @@ describe('Test of String-List', () => { const listItemTwo = initListItem(["abc", "def", "ghi"]); assert.equal(listItemOne.compareTo(listItemTwo), 1); }); + it('toString should return correct string', () => { + const listItem = initListItem(["abc", "def", "ghi"]); + assert.deepEqual(listItem.toString(), "abc def ghi"); + }); + it('toStringArray should return correct string[]', () => { + const source = ["abc", "def", "ghi"]; + const listItem = initListItem(source); + assert.deepEqual(listItem.toStringArray(), source); + }); }); function stubSectionsStrsAllocString(s?: string, opts?: StrsOptions, sections?: DependencySections): StrsItem { From 19da0c73aee1180fff04f7331b18fa8a5ec3173b Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Wed, 27 Nov 2024 05:48:51 +0000 Subject: [PATCH 063/117] chore(developer): add four additional test cases --- .../test/ldml-keyboard/test-string-list.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/common/web/types/test/ldml-keyboard/test-string-list.ts b/common/web/types/test/ldml-keyboard/test-string-list.ts index ba200413298..db5853d99d9 100644 --- a/common/web/types/test/ldml-keyboard/test-string-list.ts +++ b/common/web/types/test/ldml-keyboard/test-string-list.ts @@ -94,6 +94,11 @@ describe('Test of String-List', () => { const listItemTwo = initListItem(["abc", "def", "ghi"]); assert.isTrue(listItemOne.isEqual(listItemTwo)); }); + it('isEqual should return false for different ListItems', () => { + const listItemOne = initListItem(["abc", "def", "ghi"]); + const listItemTwo = initListItem(["abd", "def", "ghi"]); + assert.isFalse(listItemOne.isEqual(listItemTwo)); + }); it('isEqual should return false for different length ListItems', () => { const listItemOne = initListItem(["abc", "def"]); const listItemTwo = initListItem(["abc", "def", "ghi"]); @@ -116,6 +121,10 @@ describe('Test of String-List', () => { const listItem = initListItem(["abc", "def", "ghi"]); assert.isTrue(listItem.isEqual(["abc", "def", "ghi"])); }); + it('isEqual should return false for different ListItem and string[]', () => { + const listItem = initListItem(["abc", "def", "ghi"]); + assert.isFalse(listItem.isEqual(["abd", "def", "ghi"])); + }); it('isEqual should return false for different length ListItem and string[]', () => { const listItem = initListItem(["abc", "def"]); assert.isFalse(listItem.isEqual(["abc", "def", "ghi"])); @@ -159,11 +168,19 @@ describe('Test of String-List', () => { const listItem = initListItem(["abc", "def", "ghi"]); assert.deepEqual(listItem.toString(), "abc def ghi"); }); + it('toString should return correct string for empty ListItem', () => { + const listItem = new ListItem; + assert.deepEqual(listItem.toString(), ""); + }); it('toStringArray should return correct string[]', () => { const source = ["abc", "def", "ghi"]; const listItem = initListItem(source); assert.deepEqual(listItem.toStringArray(), source); }); + it('toStringArray should return correct string[] for empty ListItem', () => { + const listItem = new ListItem; + assert.deepEqual(listItem.toStringArray(), []); + }); }); function stubSectionsStrsAllocString(s?: string, opts?: StrsOptions, sections?: DependencySections): StrsItem { From 402b4065e0e39f69f0529bbdbda0b690a09fedf5 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Wed, 27 Nov 2024 06:10:45 +0000 Subject: [PATCH 064/117] chore(common/web): refactor tests for readability --- .../test/ldml-keyboard/test-string-list.ts | 300 +++++++++--------- 1 file changed, 156 insertions(+), 144 deletions(-) diff --git a/common/web/types/test/ldml-keyboard/test-string-list.ts b/common/web/types/test/ldml-keyboard/test-string-list.ts index db5853d99d9..3275c9a5162 100644 --- a/common/web/types/test/ldml-keyboard/test-string-list.ts +++ b/common/web/types/test/ldml-keyboard/test-string-list.ts @@ -4,7 +4,7 @@ import { StrsItem, StrsOptions, DependencySections, Strs } from '../../src/kmx/k import { ListIndex, ListItem } from '../../src/ldml-keyboard/string-list.js'; describe('Test of String-List', () => { - describe('should test ListIndex', () => { + describe('Test ListIndex', () => { it('can construct a ListIndex', () => { const strsItem = new StrsItem("abc"); const actual = new ListIndex(strsItem); @@ -37,149 +37,161 @@ describe('Test of String-List', () => { assert.deepEqual(listItem.toString(), expected); }); }); - describe('should test ListItem', () => { - it('fromStrings 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('fromStrings 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('fromStrings 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); - }); - it('getItemOrder 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('getItemOrder 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('getItemOrder should return -1 for a missing item', () => { - const listItem = initListItem(["abc", "def", "ghi"]); - const index = listItem.getItemOrder("jkl"); - assert.equal(index, -1); - }); - it('isEqual should return true for two empty ListItems', () => { - const listItemOne = new ListItem(); - const listItemTwo = new ListItem(); - assert.isTrue(listItemOne.isEqual(listItemTwo)); - }); - it('isEqual should return false for empty and non-empty ListItems', () => { - const listItemOne = new ListItem(); - const listItemTwo = initListItem(["abc"]); - assert.isFalse(listItemOne.isEqual(listItemTwo)); - }); - it('isEqual should return false for non-empty and empty ListItems', () => { - const listItemOne = initListItem(["abc"]); - const listItemTwo = new ListItem(); - assert.isFalse(listItemOne.isEqual(listItemTwo)); - }); - it('isEqual should return true for identical ListItems', () => { - const listItemOne = initListItem(["abc", "def", "ghi"]); - const listItemTwo = initListItem(["abc", "def", "ghi"]); - assert.isTrue(listItemOne.isEqual(listItemTwo)); - }); - it('isEqual should return false for different ListItems', () => { - const listItemOne = initListItem(["abc", "def", "ghi"]); - const listItemTwo = initListItem(["abd", "def", "ghi"]); - assert.isFalse(listItemOne.isEqual(listItemTwo)); - }); - it('isEqual should return false for different length ListItems', () => { - const listItemOne = initListItem(["abc", "def"]); - const listItemTwo = initListItem(["abc", "def", "ghi"]); - assert.isFalse(listItemOne.isEqual(listItemTwo)); - }); - }); - it('isEqual should return true for empty ListItem and string[]', () => { - const listItem = new ListItem(); - assert.isTrue(listItem.isEqual([])); - }); - it('isEqual should return false for empty ListItem and non-empty string[]', () => { - const listItem = new ListItem(); - assert.isFalse(listItem.isEqual(["abc"])); - }); - it('isEqual should return false for non-empty ListItem and empty string[]', () => { - const listItem = initListItem(["abc"]);; - assert.isFalse(listItem.isEqual([])); - }); - it('isEqual should return true for identical ListItem and string[]', () => { - const listItem = initListItem(["abc", "def", "ghi"]); - assert.isTrue(listItem.isEqual(["abc", "def", "ghi"])); - }); - it('isEqual should return false for different ListItem and string[]', () => { - const listItem = initListItem(["abc", "def", "ghi"]); - assert.isFalse(listItem.isEqual(["abd", "def", "ghi"])); - }); - it('isEqual should return false for different length ListItem and string[]', () => { - const listItem = initListItem(["abc", "def"]); - assert.isFalse(listItem.isEqual(["abc", "def", "ghi"])); - }); - it('compareTo 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('compareTo 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('compareTo 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('compareTo 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('compareTo 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('compareTo 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('compareTo 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); - }); - it('toString should return correct string', () => { - const listItem = initListItem(["abc", "def", "ghi"]); - assert.deepEqual(listItem.toString(), "abc def ghi"); - }); - it('toString should return correct string for empty ListItem', () => { - const listItem = new ListItem; - assert.deepEqual(listItem.toString(), ""); - }); - it('toStringArray should return correct string[]', () => { - const source = ["abc", "def", "ghi"]; - const listItem = initListItem(source); - assert.deepEqual(listItem.toStringArray(), source); - }); - it('toStringArray should return correct string[] for empty ListItem', () => { - const listItem = new ListItem; - assert.deepEqual(listItem.toStringArray(), []); + 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(), []); + }); + }); }); }); From acf156b965a92faf4bfcf8cded7cf9effd370379 Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Wed, 27 Nov 2024 07:02:44 +0000 Subject: [PATCH 065/117] chore(common/web): add test-unicodeset-parser.ts to test UnicodeSet --- .../test-unicodeset-parser-api.ts | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 common/web/types/test/ldml-keyboard/test-unicodeset-parser-api.ts diff --git a/common/web/types/test/ldml-keyboard/test-unicodeset-parser-api.ts b/common/web/types/test/ldml-keyboard/test-unicodeset-parser-api.ts new file mode 100644 index 00000000000..073e0d61f3d --- /dev/null +++ b/common/web/types/test/ldml-keyboard/test-unicodeset-parser-api.ts @@ -0,0 +1,24 @@ +import 'mocha'; +import { assert } from 'chai'; +import { UnicodeSet } from '../../src/ldml-keyboard/unicodeset-parser-api.js'; + +class MockUnicodeSet extends UnicodeSet { + constructor(public pattern: string, public ranges: number[][]) { + super(pattern, ranges); // does nothing + this.pattern = pattern; + this.ranges = ranges; + } +} + +describe('Test of Unicode-Parser-API', () => { + describe('Test UnicodeSet', () => { + it('can provide a correct ranges length', () => { + const unicodeSet = new MockUnicodeSet("[ħa-z]", [[0x41, 0x7A], [0x0127, 0x0127]]); + assert.equal(unicodeSet.length, 2); + }); + it('can provide a correct string representation', () => { + const unicodeSet = new MockUnicodeSet("[ħa-z]", [[0x41, 0x7A], [0x0127, 0x0127]]); + assert.deepEqual(unicodeSet.toString(), "[ħa-z]"); + }); + }); +}); \ No newline at end of file From 18d00c7701a9852157d932ff6223d6a27d660616 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 27 Nov 2024 15:34:34 +0700 Subject: [PATCH 066/117] fix(core): use `NDEBUG` flag to disable assertions in release build for VC++ This disables assertions in release builds in Windows only. Other platforms may have different outcomes. Fixes: #12619 --- common/windows/delphi/general/KeymanPaths.pas | 8 +++++++- resources/build/meson/standard.meson.build | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) 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/resources/build/meson/standard.meson.build b/resources/build/meson/standard.meson.build index 87efed5ab55..c3e4ac69cf7 100644 --- a/resources/build/meson/standard.meson.build +++ b/resources/build/meson/standard.meson.build @@ -72,6 +72,12 @@ if cpp_compiler.get_id() == 'msvc' '-D_SCL_SECURE_NO_WARNINGS', '-D_CRT_SECURE_NO_WARNINGS' ] + if get_option('buildtype') != 'debug' + # Disable assertions on release builds + defns += [ + '-DNDEBUG' + ] + endif endif if cpp_compiler.get_id() == 'emscripten' From 5dee258dac09f861764986a2c13e543bb5546c63 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Wed, 27 Nov 2024 15:37:06 +0700 Subject: [PATCH 067/117] docs(android): Add android/docs/internal/README --- android/README.md | 13 ++++++++++--- android/docs/internal/README.md | 5 +++++ 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 android/docs/internal/README.md 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/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 From 7edda3becaa1153c60ee8a93870a3711322d40fa Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Wed, 27 Nov 2024 10:16:58 +0100 Subject: [PATCH 068/117] chore(linux): address code review comments --- docs/linux/README.md | 4 ++++ docs/linux/keyman-config.md | 2 +- docs/settings/linux/launch.json | 2 +- docs/settings/linux/settings.json | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) 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, From d151d0999f1e5308a69fb3eac58a65561d4680ad Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Wed, 27 Nov 2024 11:15:43 +0100 Subject: [PATCH 069/117] refactor(common): output number of tests when running on TC This change adds the mocha-teamcity-reporter which outputs the running tests in a special format that TeamCity can interpret. This allows TC to show which tests run as well as the number of tests run. --- common/web/types/build.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/common/web/types/build.sh b/common/web/types/build.sh index b2ada0ecbc4..75273aaa2c9 100755 --- a/common/web/types/build.sh +++ b/common/web/types/build.sh @@ -80,13 +80,20 @@ 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 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." } From 21736d881759c1e880f3e177401dd15c25103beb Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Tue, 26 Nov 2024 21:57:54 +0100 Subject: [PATCH 070/117] refactor(developer): output number of tests when running on TC This change adds the mocha-teamcity-reporter which outputs the running tests in a special format that TeamCity can interpret. This allows TC to show which tests run as well as the number of tests run. Also refactor some of the build scripts to use functions. Note that we had to explicitly add `--check-coverage=false` (which is the default) to get successful builds when we run on TC. --- developer/src/common/web/utils/build.sh | 22 +++++++---- developer/src/kmc-analyze/build.sh | 9 ++++- developer/src/kmc-copy/build.sh | 9 ++++- developer/src/kmc-generate/build.sh | 9 ++++- developer/src/kmc-keyboard-info/build.sh | 23 ++++++----- developer/src/kmc-kmn/build.sh | 22 ++++++----- developer/src/kmc-ldml/build.sh | 50 +++++++++++------------- developer/src/kmc-model-info/build.sh | 15 +++++-- developer/src/kmc-model/build.sh | 16 +++++++- developer/src/kmc-model/package.json | 2 +- developer/src/kmc-package/build.sh | 25 +++++++----- developer/src/kmc/build.sh | 9 ++++- 12 files changed, 138 insertions(+), 73 deletions(-) diff --git a/developer/src/common/web/utils/build.sh b/developer/src/common/web/utils/build.sh index ddc66549937..b8137619877 100755 --- a/developer/src/common/web/utils/build.sh +++ b/developer/src/common/web/utils/build.sh @@ -46,18 +46,24 @@ function do_build() { tsc --build } -builder_run_action clean rm -rf ./build/ -builder_run_action configure verify_npm_setup -builder_run_action build do_build +function do_test() { + local MOCHA_FLAGS= + + if [[ "${TEAMCITY_GIT_PATH:-}" != "" ]]; then + # we're running in TeamCity + MOCHA_FLAGS="-reporter mocha-teamcity-reporter" + fi -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 + c8 --reporter=lcov --reporter=text --exclude-after-remap --check-coverage=false --lines $C8_THRESHOLD --statements $C8_THRESHOLD --branches $C8_THRESHOLD --functions $C8_THRESHOLD mocha ${MOCHA_FLAGS} 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 clean rm -rf ./build/ +builder_run_action configure verify_npm_setup +builder_run_action build do_build +builder_run_action test do_test +builder_run_action publish builder_publish_npm diff --git a/developer/src/kmc-analyze/build.sh b/developer/src/kmc-analyze/build.sh index a4844c6afc9..d78bd146cdf 100755 --- a/developer/src/kmc-analyze/build.sh +++ b/developer/src/kmc-analyze/build.sh @@ -26,12 +26,19 @@ builder_parse "$@" #------------------------------------------------------------------------------------------------------------------- function do_test() { + local MOCHA_FLAGS= + + if [[ "${TEAMCITY_GIT_PATH:-}" != "" ]]; then + # we're running in TeamCity + MOCHA_FLAGS="-reporter mocha-teamcity-reporter" + fi + 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 + c8 --reporter=lcov --reporter=text --lines $C8_THRESHOLD --statements $C8_THRESHOLD --branches $C8_THRESHOLD --functions $C8_THRESHOLD mocha ${MOCHA_FLAGS} } builder_run_action clean rm -rf ./build/ diff --git a/developer/src/kmc-copy/build.sh b/developer/src/kmc-copy/build.sh index 023f0c73bf8..f916bec556d 100755 --- a/developer/src/kmc-copy/build.sh +++ b/developer/src/kmc-copy/build.sh @@ -32,12 +32,19 @@ 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/ + local MOCHA_FLAGS= + + if [[ "${TEAMCITY_GIT_PATH:-}" != "" ]]; then + # we're running in TeamCity + MOCHA_FLAGS="-reporter mocha-teamcity-reporter" + fi + 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[@]}" + 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." } diff --git a/developer/src/kmc-generate/build.sh b/developer/src/kmc-generate/build.sh index 6a86a9339fe..5380ee3eb24 100755 --- a/developer/src/kmc-generate/build.sh +++ b/developer/src/kmc-generate/build.sh @@ -37,11 +37,18 @@ do_build() { } do_test() { + local MOCHA_FLAGS= + + if [[ "${TEAMCITY_GIT_PATH:-}" != "" ]]; then + # we're running in TeamCity + MOCHA_FLAGS="-reporter mocha-teamcity-reporter" + fi + eslint . cd test tsc --build cd .. - c8 --reporter=lcov --reporter=text mocha "${builder_extra_params[@]}" + c8 --reporter=lcov --reporter=text mocha ${MOCHA_FLAGS} "${builder_extra_params[@]}" } builder_run_action clean rm -rf ./build/ ./tsconfig.tsbuildinfo diff --git a/developer/src/kmc-keyboard-info/build.sh b/developer/src/kmc-keyboard-info/build.sh index c85d76db015..5ccc41a8138 100755 --- a/developer/src/kmc-keyboard-info/build.sh +++ b/developer/src/kmc-keyboard-info/build.sh @@ -32,23 +32,28 @@ 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 +} + +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 + c8 --reporter=lcov --reporter=text --exclude-after-remap --check-coverage=false mocha ${MOCHA_FLAGS} } + #------------------------------------------------------------------------------------------------------------------- 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 do_test #------------------------------------------------------------------------------------------------------------------- diff --git a/developer/src/kmc-kmn/build.sh b/developer/src/kmc-kmn/build.sh index a0732414758..5f81a367a9f 100755 --- a/developer/src/kmc-kmn/build.sh +++ b/developer/src/kmc-kmn/build.sh @@ -56,27 +56,31 @@ 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 +function do_test() { + local MOCHA_FLAGS= -#------------------------------------------------------------------------------------------------------------------- + if [[ "${TEAMCITY_GIT_PATH:-}" != "" ]]; then + # we're running in TeamCity + MOCHA_FLAGS="-reporter mocha-teamcity-reporter" + fi -if builder_start_action test; then 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 + c8 --reporter=lcov --reporter=text --lines $C8_THRESHOLD --statements $C8_THRESHOLD --branches $C8_THRESHOLD --functions $C8_THRESHOLD mocha ${MOCHA_FLAGS} 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 build do_build +builder_run_action api api-extractor run --local --verbose +builder_run_action test do_test #------------------------------------------------------------------------------------------------------------------- diff --git a/developer/src/kmc-ldml/build.sh b/developer/src/kmc-ldml/build.sh index 73a40c79d75..61fc2a695c5 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,29 @@ 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 +function do_test() { + local MOCHA_FLAGS= -builder_run_action api api-extractor run --local --verbose - -#------------------------------------------------------------------------------------------------------------------- + if [[ "${TEAMCITY_GIT_PATH:-}" != "" ]]; then + # we're running in TeamCity + MOCHA_FLAGS="-reporter mocha-teamcity-reporter" + fi -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 + c8 --reporter=lcov --reporter=text mocha ${MOCHA_FLAGS} "${builder_extra_params[@]}" +} + +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 do_test #------------------------------------------------------------------------------------------------------------------- diff --git a/developer/src/kmc-model-info/build.sh b/developer/src/kmc-model-info/build.sh index b1ba95c34b8..2563da22248 100755 --- a/developer/src/kmc-model-info/build.sh +++ b/developer/src/kmc-model-info/build.sh @@ -50,13 +50,20 @@ builder_run_action api api-extractor run --local --verbose #------------------------------------------------------------------------------------------------------------------- -if builder_start_action test; then +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 - c8 --reporter=lcov --reporter=text --exclude-after-remap --lines 80 mocha + c8 --reporter=lcov --reporter=text --exclude-after-remap --check-coverage=false --lines 80 mocha ${MOCHA_FLAGS} # TODO: remove --lines 80 and improve coverage - builder_finish_action success test -fi +} + +builder_run_action test do_test #------------------------------------------------------------------------------------------------------------------- diff --git a/developer/src/kmc-model/build.sh b/developer/src/kmc-model/build.sh index 372a145312a..7186c3ef891 100755 --- a/developer/src/kmc-model/build.sh +++ b/developer/src/kmc-model/build.sh @@ -35,10 +35,24 @@ function do_build() { npm run build } +function do_test() { + local MOCHA_FLAGS= + + if [[ "${TEAMCITY_GIT_PATH:-}" != "" ]]; then + # we're running in TeamCity + MOCHA_FLAGS="-reporter mocha-teamcity-reporter" + fi + npm run lint + cd test + tsc -b + cd .. + c8 --reporter=lcov --reporter=text mocha ${MOCHA_FLAGS} +} + 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 do_test 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..3f95b5e181b 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": [ diff --git a/developer/src/kmc-package/build.sh b/developer/src/kmc-package/build.sh index 0b2d7bda9b9..bad3bb1d183 100755 --- a/developer/src/kmc-package/build.sh +++ b/developer/src/kmc-package/build.sh @@ -30,20 +30,25 @@ builder_describe_outputs \ builder_parse "$@" -#------------------------------------------------------------------------------------------------------------------- - -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 +function do_test() { + local MOCHA_FLAGS= -if builder_start_action test; then + if [[ "${TEAMCITY_GIT_PATH:-}" != "" ]]; then + # we're running in TeamCity + MOCHA_FLAGS="-reporter mocha-teamcity-reporter" + fi eslint . cd test tsc --build cd .. - c8 --reporter=lcov --reporter=text mocha - builder_finish_action success test -fi + c8 --reporter=lcov --reporter=text mocha ${MOCHA_FLAGS} +} +#------------------------------------------------------------------------------------------------------------------- + +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 do_test builder_run_action publish builder_publish_npm diff --git a/developer/src/kmc/build.sh b/developer/src/kmc/build.sh index 6c3dfa17bd0..6e4ebc0a587 100755 --- a/developer/src/kmc/build.sh +++ b/developer/src/kmc/build.sh @@ -62,10 +62,17 @@ function do_api() { #------------------------------------------------------------------------------------------------------------------- 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/ readonly C8_THRESHOLD=50 - c8 --reporter=lcov --reporter=text --lines $C8_THRESHOLD --statements $C8_THRESHOLD --branches $C8_THRESHOLD --functions $C8_THRESHOLD mocha + c8 --reporter=lcov --reporter=text --lines $C8_THRESHOLD --statements $C8_THRESHOLD --branches $C8_THRESHOLD --functions $C8_THRESHOLD mocha ${MOCHA_FLAGS} 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." } From 6731cc44abae2ae6a61d919ac6dfb270649d0977 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Wed, 27 Nov 2024 12:13:57 +0100 Subject: [PATCH 071/117] chore(web): rename file missed in #12704 --- ...geContextAttachment.test.ts => pageContextAttachment.tests.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename web/src/test/auto/dom/cases/attachment/{pageContextAttachment.test.ts => pageContextAttachment.tests.ts} (100%) diff --git a/web/src/test/auto/dom/cases/attachment/pageContextAttachment.test.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.test.ts rename to web/src/test/auto/dom/cases/attachment/pageContextAttachment.tests.ts From 3dc3f040de0dd50bbf97a5461d5cccffa0f45ca3 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Fri, 30 Aug 2024 14:44:40 +0700 Subject: [PATCH 072/117] feat(core): implement loading KMX from blob - split keyboard loading into loading KMX file into blob and then loading the keyboard processor from the blob. - deprecate `km_core_keyboard_load` - move file access next to deprecated method. This is now the only place that loads a file in Core; unit tests have some more places that load files. - introduce GTest and add unit tests for loading from blob Cherry-picked from `epic/web-core` branch. Cherry-Pick-Commit: 1deaa323ada28a6212da06d76ef886abc9c1335c Cherry-Pick-Commit: 59019cc8b79242de3c1e2a1703083f1b89d792d7 Cherry-Pick-Commit: bc4645836838e37e696f49fa6f342e548635a91a Cherry-Pick-Commit: d06aa29956227dd3277dee32fe36a94e0828f102 Cherry-Pick-Commit: 1c88166f6eea3ebb27bb5bdd05c4704ea6afb4b3 Cherry-Pick-Commit: 069cd21ecde94730ba16cfef91a8f37a225bdcd7 Cherry-Pick-Commit: 052ae2ec35e1756eebc15c691c3d690685272638 Cherry-Pick-Commit: 11a2a3ba3a3e1bd58583438ca054f290836fcae2 Part-of: #11293 Part-of: #8093 --- core/include/keyman/keyman_core_api.h | 66 ++++++++- core/include/keyman/keyman_core_api_bits.h | 5 +- core/src/keyboard.cpp | 7 +- core/src/keyboard.hpp | 5 +- core/src/km_core_keyboard_api.cpp | 117 +++++++++++++--- core/src/kmx/kmx_file.cpp | 90 ++++-------- core/src/kmx/kmx_processevent.h | 4 +- core/src/kmx/kmx_processor.cpp | 29 +++- core/src/kmx/kmx_processor.hpp | 4 +- core/src/ldml/ldml_processor.cpp | 52 +++---- core/src/ldml/ldml_processor.hpp | 9 +- core/src/meson.build | 38 +++--- core/src/mock/mock_processor.cpp | 24 +++- core/src/mock/mock_processor.hpp | 10 +- core/src/util_normalize_table_generator.cpp | 1 - core/subprojects/.gitignore | 1 + core/subprojects/gtest.wrap | 16 +++ .../tests/unit/km_core_keyboard_api.tests.cpp | 128 ++++++++++++++++++ .../unit/kmnkbd/action_set_api.tests.cpp | 5 +- .../unit/kmnkbd/actions_get_api.tests.cpp | 4 +- .../unit/kmnkbd/actions_normalize.tests.cpp | 4 +- core/tests/unit/kmnkbd/debug_api.tests.cpp | 5 +- core/tests/unit/kmnkbd/keyboard_api.tests.cpp | 8 +- core/tests/unit/kmnkbd/state_api.tests.cpp | 5 +- .../unit/kmnkbd/state_context_api.tests.cpp | 11 +- core/tests/unit/kmx/kmx.cpp | 4 +- .../unit/kmx/kmx_external_event.tests.cpp | 4 +- core/tests/unit/kmx/kmx_imx.tests.cpp | 7 +- core/tests/unit/kmx/kmx_key_list.tests.cpp | 4 +- .../unit/ldml/context_normalization.tests.cpp | 4 +- core/tests/unit/ldml/core_ldml_min.tests.cpp | 4 +- core/tests/unit/ldml/ldml.cpp | 4 +- core/tests/unit/ldml/ldml_test_source.cpp | 6 +- core/tests/unit/ldml/meson.build | 5 +- core/tests/unit/load_kmx_file.cpp | 34 +++++ core/tests/unit/load_kmx_file.hpp | 14 ++ core/tests/unit/meson.build | 30 +++- linux/debian/libkeymancore2.symbols | 3 +- 38 files changed, 580 insertions(+), 191 deletions(-) create mode 100644 core/subprojects/gtest.wrap create mode 100644 core/tests/unit/km_core_keyboard_api.tests.cpp create mode 100644 core/tests/unit/load_kmx_file.cpp create mode 100644 core/tests/unit/load_kmx_file.hpp diff --git a/core/include/keyman/keyman_core_api.h b/core/include/keyman/keyman_core_api.h index 328965e8761..3c41182bab2 100644 --- a/core/include/keyman/keyman_core_api.h +++ b/core/include/keyman/keyman_core_api.h @@ -1007,7 +1007,11 @@ Provides read-only information about a keyboard. typedef struct { km_core_cu const * version_string; km_core_cu const * id; + + // TODO-web-core: Deprecate this field (#12497) + // KMN_DEPRECATED km_core_path_name folder_path; + km_core_option_item const * default_options; } km_core_keyboard_attrs; @@ -1022,7 +1026,7 @@ typedef struct { : Keyman keyboard ID string. `folder_path` -: Path to the unpacked folder containing the keyboard and associated resources. +: Path to the unpacked folder containing the keyboard and associated resources (deprecated). `default_options` : Set of default values for any options included in the keyboard. @@ -1096,12 +1100,16 @@ typedef struct { ## Description +DEPRECATED: use [km_core_keyboard_load_from_blob] instead. + Parse and load keyboard from the supplied path and a pointer to the loaded keyboard -into the out paramter. +into the out parameter. ## Specification ```c */ +// TODO-web-core: Deprecate this function (#12497) +// KMN_DEPRECATED_API KMN_API km_core_status km_core_keyboard_load(km_core_path_name kb_path, @@ -1140,6 +1148,60 @@ km_core_keyboard_load(km_core_path_name kb_path, ------------------------------------------------------------------------------- +# km_core_keyboard_load_from_blob() + +## Description + +Parse and load keyboard from the supplied blob and a pointer to the loaded keyboard +into the out paramter. + +## Specification + +```c */ +KMN_API +km_core_status km_core_keyboard_load_from_blob(const km_core_path_name kb_name, + const void* blob, + const size_t blob_size, + km_core_keyboard** keyboard); + +/* +``` + +## Parameters + +`kb_name` +: a string with the name of the keyboard. + +`blob` +: a byte array containing the content of a KMX/KMX+ file. + +`blob_size` +: a size_t variable with the size of the blob in bytes. + +`keyboard` +: A pointer to result variable: A pointer to the opaque keyboard + object returned by the Processor. This memory must be freed with a + call to [km_core_keyboard_dispose]. + +## Returns + +`KM_CORE_STATUS_OK` +: On success. + +`KM_CORE_STATUS_NO_MEM` +: In the event an internal memory allocation fails. + +`KM_CORE_STATUS_IO_ERROR` +: In the event the keyboard file is unparseable for any reason + +`KM_CORE_STATUS_INVALID_ARGUMENT` +: In the event `keyboard` is null. + +`KM_CORE_STATUS_OS_ERROR` +: Bit 31 (high bit) set, bits 0-30 are an OS-specific error code. + +------------------------------------------------------------------------------- + # km_core_keyboard_dispose() ## Description diff --git a/core/include/keyman/keyman_core_api_bits.h b/core/include/keyman/keyman_core_api_bits.h index e00f4698a8c..bd1f519bffe 100644 --- a/core/include/keyman/keyman_core_api_bits.h +++ b/core/include/keyman/keyman_core_api_bits.h @@ -23,7 +23,6 @@ #define _kmn_unused(x) UNUSED_ ## x __attribute__((__unused__)) #else #define _kmn_unused(x) UNUSED_ ## x - #endif #if defined _WIN32 || defined __CYGWIN__ @@ -36,7 +35,7 @@ #undef _kmn_static_flag #else // How MSVC sepcifies function level attributes adn deprecation #define _kmn_and - #define _kmn_tag_fn(a) __declspec(a) + #define _kmn_tag_fn(a) __declspec(a) #define _kmn_deprecated_flag deprecated #endif #define _kmn_export_flag dllexport @@ -48,6 +47,8 @@ #define _KM_CORE_EXT_SEPARATOR ('.') #endif +#define KMN_DEPRECATED _kmn_tag_fn(_kmn_deprecated_flag) + #if defined KM_CORE_LIBRARY_STATIC #define KMN_API _kmn_tag_fn(_kmn_static_flag) #define KMN_DEPRECATED_API _kmn_tag_fn(_kmn_deprecated_flag _kmn_and _kmn_static_flag) diff --git a/core/src/keyboard.cpp b/core/src/keyboard.cpp index 2c3a0c11b2c..0f104f9422a 100644 --- a/core/src/keyboard.cpp +++ b/core/src/keyboard.cpp @@ -17,18 +17,16 @@ void keyboard_attributes::render() // Make attributes point to the stored values above. id = _keyboard_id.c_str(); version_string = _version_string.c_str(); - folder_path = _folder_path.c_str(); default_options = _default_opts.data(); } keyboard_attributes::keyboard_attributes(std::u16string const & kbid, std::u16string const & version, - path_type const & path, options_store const &opts) : _keyboard_id(kbid), _version_string(version), - _folder_path(path), + _folder_path(""), _default_opts(opts) { // Ensure that the default_options array will be properly terminated. @@ -40,7 +38,7 @@ keyboard_attributes::keyboard_attributes(std::u16string const & kbid, keyboard_attributes::keyboard_attributes(keyboard_attributes &&rhs) : _keyboard_id(std::move(rhs._keyboard_id)), _version_string(std::move(rhs._version_string)), - _folder_path(std::move(rhs._folder_path)), + _folder_path(""), _default_opts(std::move(rhs._default_opts)) { rhs.id = rhs.version_string = nullptr; @@ -58,7 +56,6 @@ json & km::core::operator << (json & j, km::core::keyboard_attributes const & kb { j << json::object << "id" << kb.id - << "folder" << kb._folder_path << "version" << kb.version_string << "rules" << json::array << json::close; diff --git a/core/src/keyboard.hpp b/core/src/keyboard.hpp index 142bf40e860..2ca7118d870 100644 --- a/core/src/keyboard.hpp +++ b/core/src/keyboard.hpp @@ -26,6 +26,7 @@ namespace core { std::u16string _keyboard_id; std::u16string _version_string; + // unused and deprecated core::path _folder_path; std::vector