1 /*
2  * SPDX-FileCopyrightText: 2015-2015 CSSlayer <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  */
7 
8 #include "testconfig.h"
9 #include <vector>
10 #include <fcitx-config/configuration.h>
11 #include <fcitx-config/enum.h>
12 #include <fcitx-config/iniparser.h>
13 #include "fcitx-utils/log.h"
14 
15 using namespace fcitx;
16 
validate(const RawConfig & config)17 void validate(const RawConfig &config) {
18     for (const auto &item : config.subItems()) {
19         auto subConfig = config.get(item);
20         FCITX_ASSERT(subConfig->name() == item);
21         FCITX_ASSERT(subConfig);
22         FCITX_ASSERT(subConfig->parent() == &config);
23         validate(*subConfig);
24     }
25 }
26 
testBasics()27 void testBasics() {
28     TestConfig config;
29 
30     I18NString str;
31     str.set("A", "zh_CN");
32     str.set("ABCD");
33     config.i18nStringValue.setValue(str);
34     RawConfig rawConfig;
35     config.save(rawConfig);
36 
37     FCITX_ASSERT(*config.intVector == std::vector<int>{0});
38     *config.intVector.mutableValue() = std::vector<int>{1, 2};
39     FCITX_ASSERT((*config.intVector == std::vector<int>{1, 2}));
40     *config.intVector.mutableValue() = std::vector<int>{-1, 2};
41     FCITX_INFO() << *config.intVector;
42     // Invalid value is not set.
43     FCITX_ASSERT((*config.intVector == std::vector<int>{1, 2}));
44 
45     writeAsIni(rawConfig, stdout);
46 
47     FCITX_ASSERT(*rawConfig.valueByPath("IntOption") == "0");
48 
49     config.intValue.setValue(5);
50     FCITX_ASSERT(config.intValue.value() == 5);
51     // violates constrain
52     config.intValue.setValue(20);
53     // still have the old value
54     FCITX_ASSERT(config.intValue.value() == 5);
55     rawConfig.setValueByPath("EnumOption", "EnumB");
56 
57     config.subConfigValue.mutableValue()->intValue.setValue(5);
58     FCITX_ASSERT(*config.subConfigValue->intValue == 5);
59 
60     FCITX_INFO() << rawConfig;
61     config.load(rawConfig);
62     FCITX_ASSERT(config.intValue.value() == 0);
63     FCITX_ASSERT(config.enumValue.value() == TestEnum::EnumB);
64 
65     FCITX_ASSERT(config.i18nStringValue.value().match("") == "ABCD");
66     FCITX_ASSERT(config.i18nStringValue.value().match("zh_CN") == "A");
67 
68     RawConfig rawDescConfig;
69     config.dumpDescription(rawDescConfig);
70     writeAsIni(rawDescConfig, stdout);
71 
72     auto intOption = rawConfig.get("IntOption")->detach();
73     FCITX_ASSERT(intOption);
74     FCITX_ASSERT(intOption->value() == "0");
75     FCITX_ASSERT(!rawConfig.get("IntOption"));
76     FCITX_ASSERT(!intOption->parent());
77 
78     validate(rawConfig);
79     validate(rawDescConfig);
80 }
81 
testMove()82 void testMove() {
83     RawConfig config;
84     config.setValue("A");
85     auto &sub = config["B"];
86     sub.setValue("C");
87     FCITX_ASSERT(sub.parent() == &config);
88 
89     validate(config);
90 
91     auto newConfig = config;
92     FCITX_ASSERT(newConfig.value() == "A");
93     FCITX_ASSERT(newConfig.subItems() == std::vector<std::string>{"B"});
94     auto &newSub = newConfig["B"];
95     FCITX_ASSERT(newSub == sub);
96     auto copySub = newSub;
97     FCITX_ASSERT(copySub == sub);
98     FCITX_ASSERT(copySub == newSub);
99     validate(newConfig);
100 }
101 
testAssign()102 void testAssign() {
103     RawConfig config;
104     config["A"]["B"].setValue("1");
105     config["A"]["C"].setValue("2");
106     FCITX_INFO() << config;
107 
108     RawConfig newConfig;
109     newConfig = config["A"];
110     RawConfig newConfig2(config["A"]);
111     FCITX_ASSERT(newConfig2.name().empty());
112 
113     RawConfig expect;
114     expect["B"].setValue("1");
115     expect["C"].setValue("2");
116 
117     FCITX_INFO() << newConfig;
118     FCITX_INFO() << newConfig2;
119     FCITX_ASSERT(newConfig == expect);
120     FCITX_ASSERT(newConfig2 == expect);
121     validate(newConfig);
122     validate(newConfig2);
123     validate(expect);
124 
125     config["A"]["B"] = expect;
126     FCITX_ASSERT(config["A"]["B"] == expect);
127 
128     RawConfig expect2;
129     expect2["A"]["B"]["B"].setValue("1");
130     expect2["A"]["B"]["C"].setValue("2");
131     expect2["A"]["C"].setValue("2");
132     FCITX_INFO() << config;
133     FCITX_ASSERT(config == expect2);
134     validate(config);
135 }
136 
testRecursiveAssign()137 void testRecursiveAssign() {
138     {
139         RawConfig config;
140         config["A"]["B"]["C"] = "DEF";
141         config["A"] = config["A"]["B"]["C"];
142         FCITX_INFO() << config;
143         validate(config);
144     }
145     {
146         RawConfig config;
147         config["A"]["B"]["C"] = "DEF";
148         config["A"]["B"]["C"] = config["A"];
149         FCITX_INFO() << config;
150         validate(config);
151     }
152 }
153 
testSyncDefaultToCurrent()154 void testSyncDefaultToCurrent() {
155     TestConfig config;
156     RawConfig raw;
157     config.dumpDescription(raw);
158 
159     FCITX_ASSERT(raw.valueByPath("TestConfig/IntOption/DefaultValue"));
160     FCITX_ASSERT(*raw.valueByPath("TestConfig/IntOption/DefaultValue") == "0");
161 
162     raw.removeAll();
163     *config.intValue.mutableValue() = 3;
164     config.syncDefaultValueToCurrent();
165     config.dumpDescription(raw);
166     FCITX_ASSERT(raw.valueByPath("TestConfig/IntOption/DefaultValue"));
167     FCITX_ASSERT(*raw.valueByPath("TestConfig/IntOption/DefaultValue") == "3");
168 
169     raw.removeAll();
170     *config.subConfigValue.mutableValue()->intValue.mutableValue() = 10;
171     FCITX_ASSERT(*config.subConfigValue->intValue == 10);
172     config.syncDefaultValueToCurrent();
173     config.dumpDescription(raw);
174     FCITX_ASSERT(*raw.valueByPath(
175                      "SubConfigOption$TestSubConfig/IntOption/DefaultValue") ==
176                  "10");
177 
178     raw.removeAll();
179     config.subConfigValue->dumpDescription(raw);
180     config.dumpDescription(raw);
181     FCITX_ASSERT(*raw.valueByPath(
182                      "SubConfigOption$TestSubConfig/IntOption/DefaultValue") ==
183                  "10");
184 }
185 
testExtend()186 void testExtend() {
187     TestConfigExt ext;
188     *ext.intValue.mutableValue() = 4;
189     *ext.newOption.mutableValue() = {"BCD", "DEF"};
190 
191     TestConfigExt ext2;
192     ext2 = ext;
193     std::vector<std::string> expect = {"BCD", "DEF"};
194     FCITX_ASSERT(*ext.intValue == 4);
195     FCITX_ASSERT(*ext.newOption == expect);
196 }
197 
main()198 int main() {
199     testBasics();
200     testMove();
201     testAssign();
202     testRecursiveAssign();
203     testSyncDefaultToCurrent();
204     testExtend();
205     return 0;
206 }
207