test(linux): Add unit tests for mcompile#15892
Conversation
User Test ResultsTest specification and instructions User tests are not required |
This is temporary, when the transition to xkblibcommon is done, wayland will be available.
ermshiperete
left a comment
There was a problem hiding this comment.
:+1 Looks good.
As we talked in the huddle, I'm not yet approving it so that it doesn't get accidentally merged while the tests won't work on the noble ba.
| include_directories : common_include_dir | ||
| ) | ||
|
|
||
| gtest = subproject('gtest') |
There was a problem hiding this comment.
Since gtest is a dependency for the tests, I think it would better to have this line in test/meson.build (which works even if the subprojects folder is in mcompile/keymap).
| } | ||
|
|
||
|
|
||
| void get_default_layout() { |
There was a problem hiding this comment.
The function name get_default_layout suggests that it returns the default layout. A different name might be better (retrieve_default_layout? - not much better)
There was a problem hiding this comment.
done, anyway this method will go away.
| 59, 60, 61, 123, 94}; | ||
|
|
||
|
|
||
| TEST_F(KeyboardConversionTest, KMXgetKeyValUnderlyingFromKeyCodeUnderlyingBase) { |
There was a problem hiding this comment.
We could consider making this (and the others) a parameterized test
There was a problem hiding this comment.
good idea, done.
| int main(int argc, char* argv[]) { | ||
|
|
There was a problem hiding this comment.
nit:
| int main(int argc, char* argv[]) { | |
| int main(int argc, char* argv[]) { |
| LPKMX_KEYBOARD kmxfile; | ||
|
|
||
| if (!KMX_LoadKeyboard(infile, &kmxfile)) { | ||
| KMX_LogError(L"Failed to load keyboard (%d)\n", errno); |
There was a problem hiding this comment.
Do we have to delete kmxfile here?
There was a problem hiding this comment.
On failure of KMX_LoadKeyboard, kmxfile should still be nullptr.
|
|
||
| if (KMX_DoConvert(kmxfile, bDeadkeyConversion, argc, (gchar**)argv)) { // I4552F | ||
| if(!KMX_SaveKeyboard(kmxfile, outfile)) { | ||
| KMX_LogError(L"Failed to save keyboard (%d)\n", errno); |
There was a problem hiding this comment.
| KMX_LogError(L"Failed to save keyboard (%d)\n", errno); | |
| KMX_LogError(L"Failed to save keyboard (%d)\n", errno); | |
| delete kmxfile; |
| return 3; | ||
| } | ||
|
|
||
| if (KMX_DoConvert(kmxfile, bDeadkeyConversion, argc, (gchar**)argv)) { // I4552F |
There was a problem hiding this comment.
I think we can remove the I* numbers - they refer to a no-longer existing bug tracking system from earlier days of Keyman. For new code they don't make sense and should be omitted IMO.
| if (KMX_DoConvert(kmxfile, bDeadkeyConversion, argc, (gchar**)argv)) { // I4552F | |
| if (KMX_DoConvert(kmxfile, bDeadkeyConversion, argc, (gchar**)argv)) { |
There was a problem hiding this comment.
Note that those issue numbers can be found at https://github.com/keymanapp/legacy-issues
There was a problem hiding this comment.
left the numbers
| * @brief print (error) messages | ||
| * @param fmt text to print | ||
| */ | ||
| void KMX_LogError(const wchar_t* fmt, ...) { |
There was a problem hiding this comment.
Would it make more sense to use C++ style output in this function?
There was a problem hiding this comment.
Definitely, I found a nice one liner, but this is only possible with C++ 20. So I suggest to wait until we are there.
|
We have a convention for pull request titles Referencehttps://github.com/keymanapp/keyman/wiki/Pull-Request-and-Commit-workflow-notes#title I suggest changing the title to something like This way, the |
There was a problem hiding this comment.
Our filename convention for tests is tests/mcompile.tests.cpp
There was a problem hiding this comment.
renamed to keymap.test.cpp, this is what is really tested
There was a problem hiding this comment.
Should be keymap.tests.cpp (currently missing "s")
| @@ -0,0 +1,78 @@ | |||
| #include "mcompile.h" | |||
There was a problem hiding this comment.
added to all files, where the header was missing.
| return 3; | ||
| } | ||
|
|
||
| if (KMX_DoConvert(kmxfile, bDeadkeyConversion, argc, (gchar**)argv)) { // I4552F |
There was a problem hiding this comment.
Note that those issue numbers can be found at https://github.com/keymanapp/legacy-issues
| // | ||
| // 3. Write the new keyman keyboard file | ||
|
|
||
| LPKMX_KEYBOARD kmxfile; |
There was a problem hiding this comment.
| LPKMX_KEYBOARD kmxfile; | |
| LPKMX_KEYBOARD kmxfile = nullptr; |
| LPKMX_KEYBOARD kmxfile; | ||
|
|
||
| if (!KMX_LoadKeyboard(infile, &kmxfile)) { | ||
| KMX_LogError(L"Failed to load keyboard (%d)\n", errno); |
There was a problem hiding this comment.
On failure of KMX_LoadKeyboard, kmxfile should still be nullptr.
| @@ -0,0 +1,299 @@ | |||
| #include <gtest/gtest.h> | |||
There was a problem hiding this comment.
Please add standard header comment
- adding header files - renaming files and methods - restructuring meson build
There was a problem hiding this comment.
Should be keymap.tests.cpp (currently missing "s")
| @@ -1,3 +1,11 @@ | |||
| /* | |||
| * Keyman is copyright (C) 2004 - 2026 SIL International. MIT License. | |||
There was a problem hiding this comment.
Org got renamed from "SIL International" to "SIL Global" last year.
| * Keyman is copyright (C) 2004 - 2026 SIL International. MIT License. | |
| * Keyman is copyright (C) 2004 - 2026 SIL Global. MIT License. |
There was a problem hiding this comment.
| * Keyman is copyright (C) 2004 - 2026 SIL International. MIT License. | |
| * Keyman is copyright (C) SIL Global. MIT License. |
According to the style guide, we don't put the year into the header because it just adds noise. Year can be found from the git history.
| @@ -1,3 +1,9 @@ | |||
| /* | |||
| * Keyman is copyright (C) 2004 - 2026 SIL International. MIT License. | |||
There was a problem hiding this comment.
| * Keyman is copyright (C) 2004 - 2026 SIL International. MIT License. | |
| * Keyman is copyright (C) 2004 - 2026 SIL Global. MIT License. |
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| * Keyman is copyright (C) 2004 - 2024 SIL International. MIT License. | |||
| * Keyman is copyright (C) 2004 - 2026 SIL International. MIT License. | |||
There was a problem hiding this comment.
| * Keyman is copyright (C) 2004 - 2026 SIL International. MIT License. | |
| * Keyman is copyright (C) 2004 - 2026 SIL Global. MIT License. |
| @@ -1,3 +1,11 @@ | |||
| /* | |||
| * Keyman is copyright (C) 2004 - 2026 SIL International. MIT License. | |||
There was a problem hiding this comment.
| * Keyman is copyright (C) 2004 - 2026 SIL International. MIT License. | |
| * Keyman is copyright (C) 2004 - 2026 SIL Global. MIT License. |
| } | ||
| } | ||
|
|
||
| delete kmxfile; |
There was a problem hiding this comment.
I think we still need this.
There was a problem hiding this comment.
done, back again
| @@ -1,3 +1,9 @@ | |||
| /* | |||
| * Keyman is copyright (C) 2004 - 2026 SIL International. MIT License. | |||
There was a problem hiding this comment.
| * Keyman is copyright (C) 2004 - 2026 SIL International. MIT License. | |
| * Keyman is copyright (C) 2004 - 2026 SIL Global. MIT License. |
There was a problem hiding this comment.
done, years erased, too
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| * Keyman is copyright (C) 2004 - 2024 SIL International. MIT License. | |||
| * Keyman is copyright (C) 2004 - 2026 SIL International. MIT License. | |||
There was a problem hiding this comment.
| * Keyman is copyright (C) 2004 - 2026 SIL International. MIT License. | |
| * Keyman is copyright (C) 2004 - 2026 SIL Global. MIT License. |
There was a problem hiding this comment.
done, years erased, too
| @@ -1,3 +1,9 @@ | |||
| /* | |||
| * Keyman is copyright (C) 2004 - 2026 SIL International. MIT License. | |||
There was a problem hiding this comment.
| * Keyman is copyright (C) 2004 - 2026 SIL International. MIT License. | |
| * Keyman is copyright (C) 2004 - 2026 SIL Global. MIT License. |
There was a problem hiding this comment.
done, years erased, too
Co-authored-by: Eberhard Beilharz <ermshiperete@users.noreply.github.com>
…-keyboard-support-unit-tests' into feat/linux/mnemonic-keyboard-support-unit-tests
| this->keycode = k; | ||
| this->expected_char = e; | ||
| this->layout = l; | ||
| this->shiftstate = s; |
There was a problem hiding this comment.
Is this necessary if we have keycode(k) etc above? Seems to be doppelt gemoppelt 😄
| } | ||
|
|
||
| guint get_keycode() { | ||
| return keycode; |
There was a problem hiding this comment.
nit: indentation is wrong. Per coding style we indent each level by 2. The .editorconfig file should give you that for free if the extension is installed in vscode.
| return keycode; | |
| return keycode; |
| expected_keysyms = e; | ||
| layout = l; | ||
| shiftstate = s; |
| EXPECT_EQ(keycodes.size(), expected_keysyms.size()) << "Keycodes and expected keysyms vectors must be of the same size."; | ||
| for (guint k = 0; k < keycodes.size() && k < expected_keysyms.size(); k++) { |
There was a problem hiding this comment.
I think it doesn't make sense to continue if the the two vectors have different size, so we could use ASSERT_EQ here. That would also simplify the for loop slightly. Also, since we're using a std vector it doesn't really make sense to use a Gnome type for k - doesn't really matter but will reduce dependency. (I'm not sure - is there a uint or should it be unsigned int).
| EXPECT_EQ(keycodes.size(), expected_keysyms.size()) << "Keycodes and expected keysyms vectors must be of the same size."; | |
| for (guint k = 0; k < keycodes.size() && k < expected_keysyms.size(); k++) { | |
| ASSERT_EQ(keycodes.size(), expected_keysyms.size()) << "Keycodes and expected keysyms vectors must be of the same size."; | |
| for (uint k = 0; k < keycodes.size(); k++) { |
There was a problem hiding this comment.
When ASSERT_* fails, doesn't it prevent all further instantiations from running?
| INSTANTIATE_TEST_SUITE_P(AltGrUs, | ||
| GetKeyValUnderlyingFromKeyCodeUnderlyingTest, | ||
| testing::ValuesIn(KeyboardTestParameters( | ||
| {u'a', u'b', u'c', u'd', u'e', u'f', u'g', u'h', u'i', u'j', u'k', |
There was a problem hiding this comment.
It would be good to break the lines at the same place for all the tests so that it's easier to see the differences in the data between tests.
| keycode = k; | ||
| expected_char = e; | ||
| layout = l; | ||
| shiftstate = s; |
|
|
||
| }; | ||
|
|
||
| class GetKeyValFromKeyCodeTestParameters { |
There was a problem hiding this comment.
What's the difference to KeyboardTestParameters ?
There was a problem hiding this comment.
There is one more element for caps.
- formatting - improved constructors
| AltGrDe, | ||
| GetKeyValUnderlyingFromKeyCodeUnderlyingTest, | ||
| testing::ValuesIn(KeyboardTestParameters( | ||
| {u'æ', u'\xfffe', u'¢', u'ð', u'\xfffe', u'\xfffe', u'\xfffe', u'\xfffe', u'\xfffe', u'\xffff', |
There was a problem hiding this comment.
Why is it that we have u'\xffff' for some values and u'\xfffe' or u'\000' for others?
| expected_keysyms = e; | ||
| layout = l; | ||
| shiftstate = s; | ||
| caps = c; |
There was a problem hiding this comment.
| expected_keysyms = e; | |
| layout = l; | |
| shiftstate = s; | |
| caps = c; |
ermshiperete
left a comment
There was a problem hiding this comment.
Oops, forgot to check devin.ai! That found a few issues that might cause problems in the future.
| giomm_dep = dependency('giomm-2.4') | ||
| glibmm_dep = dependency('glibmm-2.4') |
There was a problem hiding this comment.
Since these are only used in tests we should probably move them to test/meson.build - unless you'll need them to be here in a later PR.
Flagged by devin.ai:
giomm/glibmm dependencies fetched unconditionally despite only being needed for tests
In linux/mcompile/keymap/meson.build:12-13, giomm-2.4 and glibmm-2.4 are declared as unconditional dependencies at configure time, even though they are only used in the test executable (test/meson.build:9). This means the main mcompile build will fail at configure time if these packages are not installed, even though the main binary doesn't need them. Consider wrapping these in a required: false or conditionalizing on whether tests are enabled, or moving the dependency declarations into test/meson.build.
| @@ -582,3 +586,28 @@ FILE* Open_File(const KMX_CHAR* filename, const KMX_CHAR* mode) { | |||
| return fopen(cpath.c_str(), cmode.c_str()); | |||
There was a problem hiding this comment.
Flagged by devin.ai:
| return fopen(cpath.c_str(), cmode.c_str()); | |
| return fopen(filename, mode); |
Hmm, looks GH has a problem displaying this change. What I try to suggest is only keeping the first line (line 582, return fopen(filename, mode);) and deleting the next 4 lines that are unreachable (lines 583-586).
Co-authored-by: Eberhard Beilharz <ermshiperete@users.noreply.github.com>
Co-authored-by: Eberhard Beilharz <ermshiperete@users.noreply.github.com>
Co-authored-by: Eberhard Beilharz <ermshiperete@users.noreply.github.com>
Co-authored-by: Eberhard Beilharz <ermshiperete@users.noreply.github.com>
@keymanapp-test-bot skip
This is a first try to add unit tests to mcompile.
There is a new file
converter.cppcontaining a minimal main. This allows the tests to have an own main provided by googletest.Since gsettings are used, there is the need for new include files and new library dependencies.
The separation of converter.cpp required some refactoring of the header files.