1 /*
2 * SPDX-FileCopyrightText: 2020~2020 CSSlayer <wengxt@gmail.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-or-later
5 *
6 */
7 #include "luaaddon_public.h"
8 #include "testdir.h"
9 #include "testfrontend_public.h"
10 #include "testim_public.h"
11 #include <fcitx-utils/eventdispatcher.h>
12 #include <fcitx-utils/log.h>
13 #include <fcitx-utils/standardpath.h>
14 #include <fcitx-utils/testing.h>
15 #include <fcitx/addonmanager.h>
16 #include <fcitx/inputmethodmanager.h>
17 #include <fcitx/instance.h>
18 #include <iostream>
19 #include <thread>
20
21 using namespace fcitx;
22
scheduleEvent(EventDispatcher * dispatcher,Instance * instance)23 void scheduleEvent(EventDispatcher *dispatcher, Instance *instance) {
24 dispatcher->schedule([instance]() {
25 auto luaaddonloader =
26 instance->addonManager().addon("luaaddonloader", true);
27 FCITX_ASSERT(luaaddonloader);
28 auto luaaddon = instance->addonManager().addon("testlua");
29 FCITX_ASSERT(luaaddon);
30 auto imeapi = instance->addonManager().addon("imeapi");
31 FCITX_ASSERT(imeapi);
32 });
33 dispatcher->schedule([dispatcher, instance]() {
34 // Setup the input method group with two input method
35 auto groupName = instance->inputMethodManager().currentGroup();
36 InputMethodGroup group(groupName);
37 group.inputMethodList().push_back(InputMethodGroupItem("keyboard-us"));
38 group.inputMethodList().push_back(InputMethodGroupItem("testim"));
39 group.setDefaultInputMethod("testim");
40 instance->inputMethodManager().setGroup(group);
41
42 auto testfrontend = instance->addonManager().addon("testfrontend");
43 auto testim = instance->addonManager().addon("testim");
44 auto luaaddon = instance->addonManager().addon("testlua");
45 testim->call<ITestIM::setHandler>(
46 [](const InputMethodEntry &, KeyEvent &keyEvent) {
47 if (keyEvent.key().states() != KeyState::NoState ||
48 keyEvent.isRelease()) {
49 return;
50 }
51 auto s = Key::keySymToUTF8(keyEvent.key().sym());
52 if (!s.empty()) {
53 keyEvent.inputContext()->commitString(s);
54 keyEvent.filterAndAccept();
55 }
56 });
57 auto uuid =
58 testfrontend->call<ITestFrontend::createInputContext>("testapp");
59 auto ic = instance->inputContextManager().findByUUID(uuid);
60 FCITX_ASSERT(ic);
61
62 // Test with the converter in test.lua
63 testfrontend->call<ITestFrontend::keyEvent>(uuid, Key("a"), false);
64 testfrontend->call<ITestFrontend::keyEvent>(uuid, Key("b"), false);
65 testfrontend->call<ITestFrontend::keyEvent>(uuid, Key("c"), false);
66 testfrontend->call<ITestFrontend::keyEvent>(uuid, Key("d"), false);
67
68 // Test lua currentInputMethod
69 auto ret = luaaddon->call<ILuaAddon::invokeLuaFunction>(
70 ic, "testInputMethod", RawConfig{});
71 FCITX_INFO() << ret;
72 assert(ret.value() == "keyboard-us");
73
74 testfrontend->call<ITestFrontend::keyEvent>(uuid, Key("Control+space"),
75 false);
76
77 // Test lua currentProgram
78 ret = luaaddon->call<ILuaAddon::invokeLuaFunction>(ic, "testProgram",
79 RawConfig{});
80 FCITX_INFO() << ret;
81 assert(ret.value() == "testapp");
82
83 // Test lua currentInputMethod after ctrl space
84 ret = luaaddon->call<ILuaAddon::invokeLuaFunction>(
85 ic, "testInputMethod", RawConfig{});
86 FCITX_INFO() << ret;
87 assert(ret.value() == "testim");
88
89 // Test with complex value with invokeLuaFunction
90 FCITX_ASSERT(luaaddon);
91 RawConfig config;
92 config["A"].setValue("5");
93 config["A"]["Q"].setValue("4");
94 FCITX_INFO() << config;
95 ret = luaaddon->call<ILuaAddon::invokeLuaFunction>(ic, "testInvoke",
96 config);
97 FCITX_INFO() << ret;
98 assert(ret["B"]["E"]["F"].value() == "7");
99 RawConfig strConfig;
100 strConfig.setValue("ABC");
101 ret = luaaddon->call<ILuaAddon::invokeLuaFunction>(ic, "testInvoke",
102 strConfig);
103 assert(ret.value() == "DEF");
104 FCITX_INFO() << ret;
105
106 std::string testString = "ABC测试DEF";
107 strConfig.setValue(testString);
108 ret = luaaddon->call<ILuaAddon::invokeLuaFunction>(
109 ic, "testUtf16Conversion", strConfig);
110 uint16_t data[] = {0x41, 0x42, 0x43, 0x6d4b, 0x8bd5, 0xd801,
111 0xdc12, 0x44, 0x45, 0x46, 0x0};
112 FCITX_ASSERT(ret.value().size() == sizeof(data));
113 FCITX_ASSERT(memcmp(ret.value().data(), data, sizeof(data)) == 0);
114
115 strConfig.setValue(ret.value());
116 ret = luaaddon->call<ILuaAddon::invokeLuaFunction>(
117 ic, "testUtf8Conversion", strConfig);
118 FCITX_ASSERT(ret.value() == testString) << ret;
119
120 dispatcher->detach();
121 instance->exit();
122 });
123 }
124
runInstance()125 void runInstance() {}
126
main()127 int main() {
128 setupTestingEnvironment(
129 TESTING_BINARY_DIR,
130 {"src/addonloader", StandardPath::fcitxPath("addondir")},
131 {"test", TESTING_SOURCE_DIR "/test",
132 StandardPath::fcitxPath("pkgdatadir", "testing")});
133
134 fcitx::Log::setLogRule("default=5,lua=5");
135 char arg0[] = "testlua";
136 char arg1[] = "--disable=all";
137 char arg2[] = "--enable=testim,testfrontend,luaaddonloader,imeapi,testlua";
138 char *argv[] = {arg0, arg1, arg2};
139 Instance instance(FCITX_ARRAY_SIZE(argv), argv);
140 setenv("FCITX_DATA_HOME", "/Invalid/Path", 1);
141 setenv("FCITX_CONFIG_HOME", "/Invalid/Path", 1);
142 instance.addonManager().registerDefaultLoader(nullptr);
143 EventDispatcher dispatcher;
144 dispatcher.attach(&instance.eventLoop());
145 std::thread thread(scheduleEvent, &dispatcher, &instance);
146 instance.exec();
147 thread.join();
148
149 return 0;
150 }
151