1 //
2 // Copyright RIME Developers
3 // Distributed under the BSD License
4 //
5 // 2011-04-06 Zou xu <zouivex@gmail.com>
6 //
7 
8 #include <gtest/gtest.h>
9 #include <rime/component.h>
10 #include <rime/config.h>
11 
12 using namespace rime;
13 
14 class RimeConfigTest : public ::testing::Test {
15  protected:
16   RimeConfigTest() = default;
17 
SetUp()18   virtual void SetUp() {
19     component_.reset(new ConfigComponent<ConfigLoader>);
20     config_.reset(component_->Create("config_test"));
21   }
22 
TearDown()23   virtual void TearDown() {
24   }
25 
26   the<Config::Component> component_;
27   the<Config> config_;
28 };
29 
TEST(RimeConfigComponentTest,RoundTrip)30 TEST(RimeConfigComponentTest, RoundTrip) {
31   // registration
32   Registry& r = Registry::instance();
33   r.Register(
34       "test_config",
35       new ConfigComponent<ConfigLoader, UserConfigResourceProvider>(
36           [](ConfigLoader* loader) {
37             loader->set_auto_save(true);
38           }));
39   // find component
40   Config::Component* cc = Config::Require("test_config");
41   ASSERT_TRUE(cc != NULL);
42   // create config and write modifications to file
43   {
44     the<Config> config(cc->Create("config_round_trip_test"));
45     EXPECT_TRUE(bool(config));
46     EXPECT_TRUE(config->SetString("key", "value"));
47   }
48   // read from file and verify contents
49   {
50     the<Config> config(cc->Create("config_round_trip_test"));
51     EXPECT_TRUE(bool(config));
52     string value;
53     EXPECT_TRUE(config->GetString("key", &value));
54     EXPECT_EQ("value", value);
55   }
56   r.Unregister("test_config");
57 }
58 
TEST(RimeConfigItemTest,NullItem)59 TEST(RimeConfigItemTest, NullItem) {
60   ConfigItem item;
61   EXPECT_EQ(ConfigItem::kNull, item.type());
62 }
63 
TEST_F(RimeConfigTest,Config_IsNull)64 TEST_F(RimeConfigTest, Config_IsNull) {
65   bool is_null = config_->IsNull("terrans/tank");
66   EXPECT_FALSE(is_null);
67 
68   is_null = config_->IsNull("protoss/tank");
69   EXPECT_TRUE(is_null);
70 }
71 
TEST_F(RimeConfigTest,Config_GetBool)72 TEST_F(RimeConfigTest, Config_GetBool) {
73   bool ret, value;
74   ret = config_->GetBool("terrans/tank/seiged", &value);
75   EXPECT_TRUE(ret);
76   EXPECT_FALSE(value);
77 
78   ret = config_->GetBool("zerg/lurker/burrowed", &value);
79   EXPECT_TRUE(ret);
80   EXPECT_TRUE(value);
81 }
82 
TEST_F(RimeConfigTest,Config_GetInt)83 TEST_F(RimeConfigTest, Config_GetInt) {
84   bool ret;
85   int value;
86   ret = config_->GetInt("terrans/supply/produced", &value);
87   EXPECT_TRUE(ret);
88   EXPECT_EQ(28, value);
89 
90   ret = config_->GetInt("zerg/zergling/lost", &value);
91   EXPECT_TRUE(ret);
92   EXPECT_EQ(1234, value);
93 }
94 
TEST_F(RimeConfigTest,Config_GetDouble)95 TEST_F(RimeConfigTest, Config_GetDouble) {
96   bool ret;
97   double value;
98   ret = config_->GetDouble("terrans/math/pi", &value);
99   EXPECT_TRUE(ret);
100   EXPECT_EQ(3.1415926, value);
101 
102   ret = config_->GetDouble("protoss/battery/energy", &value);
103   EXPECT_TRUE(ret);
104   EXPECT_EQ(10.111, value);
105 }
106 
TEST_F(RimeConfigTest,Config_GetString)107 TEST_F(RimeConfigTest, Config_GetString) {
108   bool ret;
109   string value;
110   ret = config_->GetString("protoss/residence", &value);
111   EXPECT_TRUE(ret);
112   EXPECT_EQ("Aiur", value);
113 
114   ret = config_->GetString("zerg/queen", &value);
115   EXPECT_TRUE(ret);
116   EXPECT_EQ("Kerrigan", value);
117 }
118 
TEST_F(RimeConfigTest,Config_GetList)119 TEST_F(RimeConfigTest, Config_GetList) {
120   an<ConfigList> p;
121   p = config_->GetList("protoss/air_force");
122   ASSERT_TRUE(bool(p));
123   ASSERT_EQ(4, p->size());
124   an<ConfigValue> element;
125   string value;
126   element = p->GetValueAt(0);
127   ASSERT_TRUE(bool(element));
128   ASSERT_TRUE(element->GetString(&value));
129   EXPECT_EQ("scout", value);
130   element = p->GetValueAt(3);
131   ASSERT_TRUE(bool(element));
132   ASSERT_TRUE(element->GetString(&value));
133   EXPECT_EQ("arbiter", value);
134 
135 }
136 
TEST_F(RimeConfigTest,Config_GetMap)137 TEST_F(RimeConfigTest, Config_GetMap) {
138   an<ConfigMap> p;
139   p = config_->GetMap("terrans/tank/cost");
140   ASSERT_TRUE(bool(p));
141   EXPECT_FALSE(p->HasKey("rime"));
142   ASSERT_TRUE(p->HasKey("time"));
143   an<ConfigValue> item;
144   string time;
145   int mineral = 0;
146   int gas = 0;
147   item = p->GetValue("time");
148   ASSERT_TRUE(bool(item));
149   ASSERT_TRUE(item->GetString(&time));
150   EXPECT_EQ("30 seconds", time);
151   item = p->GetValue("mineral");
152   ASSERT_TRUE(bool(item));
153   ASSERT_TRUE(item->GetInt(&mineral));
154   EXPECT_EQ(150, mineral);
155   item = p->GetValue("gas");
156   ASSERT_TRUE(bool(item));
157   ASSERT_TRUE(item->GetInt(&gas));
158   EXPECT_EQ(100, gas);
159 }
160 
TEST(RimeConfigWriterTest,Greetings)161 TEST(RimeConfigWriterTest, Greetings) {
162   the<Config> config(new Config);
163   ASSERT_TRUE(bool(config));
164   // creating contents
165   EXPECT_TRUE(config->SetItem("/", New<ConfigMap>()));
166   an<ConfigItem> terran_greetings = New<ConfigValue>("Greetings, Terrans!");
167   an<ConfigItem> zerg_greetings = New<ConfigValue>("Zergsss are coming!");
168   an<ConfigItem> zergs_coming = New<ConfigValue>(true);
169   an<ConfigItem> zergs_population = New<ConfigValue>(1000000);
170   EXPECT_TRUE(config->SetItem("greetings", terran_greetings));
171   EXPECT_TRUE(config->SetItem("zergs/overmind/greetings", zerg_greetings));
172   EXPECT_TRUE(config->SetItem("zergs/going", zergs_coming));
173   EXPECT_TRUE(config->SetItem("zergs/statistics/population", zergs_population));
174   // will not create subkeys over an existing value node
175   EXPECT_FALSE(config->SetItem("zergs/going/home", zerg_greetings));
176   // saving
177   EXPECT_TRUE(config->SaveToFile("config_writer_test.yaml"));
178   // verify
179   the<Config> config2(new Config);
180   ASSERT_TRUE(bool(config2));
181   EXPECT_TRUE(config2->LoadFromFile("config_writer_test.yaml"));
182   string the_greetings;
183   EXPECT_TRUE(config2->GetString("greetings", &the_greetings));
184   EXPECT_EQ("Greetings, Terrans!", the_greetings);
185   EXPECT_TRUE(config2->GetString("zergs/overmind/greetings", &the_greetings));
186   EXPECT_EQ("Zergsss are coming!", the_greetings);
187   bool coming = false;
188   EXPECT_TRUE(config2->GetBool("zergs/going", &coming));
189   EXPECT_TRUE(coming);
190   int population = 0;
191   EXPECT_TRUE(config2->GetInt("zergs/statistics/population", &population));
192   EXPECT_EQ(1000000, population);
193   EXPECT_FALSE(config2->GetString("zergs/going/home", &the_greetings));
194   // modifying tree
195   EXPECT_TRUE(config2->SetInt("zergs/statistics/population", population / 2));
196   EXPECT_TRUE(config2->SetString("protoss/residence", "Aiur"));
197   EXPECT_TRUE(config2->SetItem("zergs/overmind", nullptr));
198   EXPECT_TRUE(config2->SaveToFile("config_rewriter_test.yaml"));
199   // verify
200   the<Config> config3(new Config);
201   ASSERT_TRUE(bool(config3));
202   EXPECT_TRUE(config3->LoadFromFile("config_rewriter_test.yaml"));
203   EXPECT_TRUE(config3->GetInt("zergs/statistics/population", &population));
204   EXPECT_EQ(500000, population);
205   string value;
206   EXPECT_TRUE(config3->GetString("protoss/residence", &value));
207   EXPECT_EQ("Aiur", value);
208   // deleted
209   EXPECT_FALSE(config3->GetString("zergs/overmind/greetings", &value));
210   EXPECT_FALSE(config3->GetMap("zergs/overmind"));
211 }
212 
TEST(RimeConfigxxTest,Operations)213 TEST(RimeConfigxxTest, Operations) {
214   Config config;
215   config["str"] = "STR";
216   config["nested"]["bool"] = true;
217   config["nested"]["int"] = 1000000;
218   config["nested"]["greetings"] = New<ConfigValue>("Hello!");
219   config["list"][0] = New<ConfigMap>();
220   config["list"][0]["abc"] = "ABC";
221   config["list"].Append(New<ConfigMap>());
222   config["list"][1]["abc"] = "ZYX";
223   config["list"][2] = config["nested"]["greetings"];
224   config["list"][3]["abc"] = "123";
225   config["str"].Clear();
226   EXPECT_TRUE(config["str"].IsNull());
227   EXPECT_EQ(true, config["nested"]["bool"].ToBool());
228   EXPECT_EQ(1000000, config["nested"]["int"].ToInt());
229   EXPECT_EQ("Hello!", config["nested"]["greetings"].ToString());
230   EXPECT_TRUE(config["list"].IsList());
231   EXPECT_EQ(4, config["list"].size());
232   EXPECT_EQ("123", config["list"][3]["abc"].ToString());
233   EXPECT_EQ("Hello!", config["list"][2].ToString());
234   an<ConfigItem> v1(config["list"][2]);
235   an<ConfigItem> v2(config["nested"]["greetings"]);
236   EXPECT_EQ(v1, v2);
237   EXPECT_TRUE(config.modified());
238   EXPECT_TRUE(config.SaveToFile("rime_configxx_test.yaml"));
239   EXPECT_TRUE(config.LoadFromFile("rime_configxx_test.yaml"));
240   EXPECT_TRUE(config["str"].IsNull());
241   EXPECT_FALSE(config.modified());
242   EXPECT_EQ("Hello!", config["nested"]["greetings"].ToString());
243   config["list"].Append(New<ConfigValue>("orz"));
244   EXPECT_TRUE(config.modified());
245   ConfigMapEntryRef r(config["nested"]["greetings"]);
246   EXPECT_EQ("Hello!", r.ToString());
247 }
248 
TEST(RimeConfigListKeyPathTest,Greetings)249 TEST(RimeConfigListKeyPathTest, Greetings) {
250   int id = 0;
251   int value = 0;
252   the<Config> config(new Config);
253   ASSERT_TRUE(bool(config));
254   // append items
255   EXPECT_TRUE(config->SetInt("list/@next/id", 1));
256   EXPECT_TRUE(config->SetInt("list/@last/value", 100));
257   EXPECT_TRUE(config->SetInt("list/@next/id", 2));
258   EXPECT_TRUE(config->SetInt("list/@last/value", 200));
259   ASSERT_TRUE(bool(config->GetList("list")));
260   ASSERT_EQ(2, config->GetList("list")->size());
261   value = 0;
262   EXPECT_TRUE(config->GetInt("list/@0/value", &value));
263   EXPECT_EQ(100, value);
264   value = 0;
265   EXPECT_TRUE(config->GetInt("list/@1/value", &value));
266   EXPECT_EQ(200, value);
267   // insert items
268   EXPECT_TRUE(config->SetInt("list/@before 0/id", 3));
269   EXPECT_TRUE(config->SetInt("list/@0/value", 50));
270   EXPECT_TRUE(config->SetInt("list/@after last/id", 4));
271   EXPECT_TRUE(config->SetInt("list/@last/value", 400));
272   ASSERT_EQ(4, config->GetList("list")->size());
273   value = 0;
274   EXPECT_TRUE(config->GetInt("list/@0/value", &value));
275   EXPECT_EQ(50, value);
276   value = 0;
277   EXPECT_TRUE(config->GetInt("list/@1/value", &value));
278   EXPECT_EQ(100, value);
279   value = 0;
280   EXPECT_TRUE(config->GetInt("list/@2/value", &value));
281   EXPECT_EQ(200, value);
282   value = 0;
283   EXPECT_TRUE(config->GetInt("list/@3/value", &value));
284   EXPECT_EQ(400, value);
285   // refer to last item in an empty list
286   config->GetList("list")->Clear();
287   ASSERT_EQ(0, config->GetList("list")->size());
288   config->SetInt("list/@after last/id", 5);
289   EXPECT_EQ(1, config->GetList("list")->size());
290   id = 0;
291   EXPECT_TRUE(config->GetInt("list/@last/id", &id));
292   EXPECT_EQ(5, id);
293   config->GetList("list")->Clear();
294   ASSERT_EQ(0, config->GetList("list")->size());
295   config->SetInt("list/@before last/id", 6);
296   EXPECT_EQ(1, config->GetList("list")->size());
297   id = 0;
298   EXPECT_TRUE(config->GetInt("list/@last/id", &id));
299   EXPECT_EQ(6, id);
300 }
301