1 #include "run/Config.h"
2 #include "catch.hpp"
3 #include "io/FileManager.h"
4 #include "io/FileSystem.h"
5 #include "objects/containers/FlatMap.h"
6 #include "objects/utility/Streams.h"
7 
8 using namespace Sph;
9 
10 TEST_CASE("Config serialize", "[config]") {
11     Config config;
12     SharedPtr<ConfigNode> node = config.addNode("node");
13     node->set("number", 5);
14     node->set("string", String("test"));
15 
16     const String serialized = config.write();
17     REQUIRE(serialized == R"("node" [
18   "number" = 5
19   "string" = "test"
20 ]
21 
22 )");
23 }
24 
25 TEST_CASE("Config write and read", "[config]") {
26     Config config;
27     SharedPtr<ConfigNode> node1 = config.addNode("node1");
28     node1->set("value1", 5.31_f);
29     node1->set("count1", 3);
30     node1->set("path1", Path("test"));
31 
32     SharedPtr<ConfigNode> node2 = config.addNode("node2");
33     node2->set("value2", 3.14_f);
34     node2->set("text2", String(L"test \u03C1"));
35     node2->set("vector2", Vector(1._f, 2._f, 3._f));
36 
37     String serialized = config.write();
38 
39     StringTextInputStream ss(serialized);
40     REQUIRE_NOTHROW(config.read(ss));
41 
42     FlatMap<String, ConfigNode*> readNodes;
__anon60950e290102(const String& name, ConfigNode& node) 43     config.enumerate([&](const String& name, ConfigNode& node) { //
44         readNodes.insert(name, &node);
45     });
46 
47     REQUIRE(readNodes.size() == 2);
48     REQUIRE(readNodes.contains("node1"));
49     REQUIRE(readNodes.contains("node2"));
50 
51     ConfigNode* readNode1 = readNodes["node1"];
52     REQUIRE(readNode1->get<Float>("value1") == 5.31_f);
53     REQUIRE(readNode1->get<int>("count1") == 3);
54     REQUIRE(readNode1->get<Path>("path1") == Path("test"));
55     REQUIRE_THROWS_AS(readNode1->get<Float>("dummy"), ConfigException);
56     REQUIRE_THROWS_AS(readNode1->get<int>("value1"), ConfigException);
57 
58     ConfigNode* readNode2 = readNodes["node2"];
59     REQUIRE(readNode2->get<Float>("value2") == 3.14_f);
60     REQUIRE(readNode2->get<String>("text2") == L"test \u03C1");
61     REQUIRE(readNode2->get<Vector>("vector2") == Vector(1._f, 2._f, 3._f));
62 }
63 
64 TEST_CASE("Config write and read children", "[config]") {
65     Config config;
66     SharedPtr<ConfigNode> rootNode = config.addNode("root");
67     rootNode->set("rootValue", 1.5_f);
68 
69     SharedPtr<ConfigNode> childNode = rootNode->addChild("child");
70     childNode->set("childValue", 5.1_f);
71 
72     String serialized = config.write();
73 
74     StringTextInputStream ss(serialized);
75     REQUIRE_NOTHROW(config.read(ss));
76     SharedPtr<ConfigNode> readRootNode = config.getNode("root");
77     REQUIRE(readRootNode->size() == 1);
78     REQUIRE(readRootNode->get<Float>("rootValue") == 1.5_f);
79     REQUIRE_THROWS_AS(readRootNode->get<Float>("childValue"), ConfigException);
80 
81     SharedPtr<ConfigNode> readChildNode = readRootNode->getChild("child");
82     REQUIRE(readChildNode->size() == 1);
83     REQUIRE(readChildNode->get<Float>("childValue") == 5.1_f);
84 }
85 
86 TEST_CASE("Config file I/O", "[config]") {
87     Config config;
88     SharedPtr<ConfigNode> node = config.addNode("node");
89     node->set("value", 5.31_f);
90     node->set("count", 3);
91 
92     String text(L"\u03B1\u03B2\u03B3");
93     node->set("text", text);
94 
95     RandomPathManager manager;
96     Path path = manager.getPath(L"\u03B1sph"); // must work with unicode paths
97     REQUIRE_NOTHROW(config.save(path));
98     REQUIRE(FileSystem::pathExists(path));
99     REQUIRE(FileSystem::fileSize(path) > 20);
100 
101     Config loaded;
102     REQUIRE_NOTHROW(loaded.load(path));
103     node = loaded.getNode("node");
104     REQUIRE(node->get<Float>("value") == 5.31_f);
105     REQUIRE(node->get<int>("count") == 3);
106     REQUIRE(node->get<String>("text") == text);
107 
108     REQUIRE_THROWS(loaded.load(Path("nonexistent")));
109 }
110