Audacity 3.2.0
SettingsTestsCommon.cpp
Go to the documentation of this file.
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*!********************************************************************
3
4 Audacity: A Digital Audio Editor
5
6 AudioSegmentSampleViewTest.cpp
7
8 Vitaly Sverchinsky
9
10**********************************************************************/
11
12#include <catch2/catch.hpp>
13#include "BasicSettings.h"
14
15bool IsSame(const wxArrayString& arr, std::initializer_list<wxString> list, bool compareWithCase = true)
16{
17 if(arr.size() != list.size())
18 return false;
19 for(auto& str : list)
20 {
21 if(std::find_if(
22 arr.begin(),
23 arr.end(),
24 [&](const auto& value) { return str.IsSameAs(value, compareWithCase); }
25 ) == arr.end())
26 {
27 return false;
28 }
29 }
30 return true;
31}
32
33struct Stringifyable final
34{
35 long value;
36
37 bool operator ==(const Stringifyable& other) const
38 {
39 return value == other.value;
40 }
41};
42
43wxString wxToString(const Stringifyable& obj)
44{
45 return wxString::Format("%ld", obj.value);
46}
47
48bool wxFromString(const wxString& str, Stringifyable* obj)
49{
50 if(str.ToLong(&obj->value))
51 return true;
52 return false;
53}
54
56{
57 bool orangeValue;
58 REQUIRE(settings.Write("orange", true));
59 REQUIRE(settings.Read("orange", &orangeValue));
60 REQUIRE(orangeValue == true);
61
62 int appleValue;
63 REQUIRE(settings.Write("apple", 3));
64 REQUIRE(settings.Read("apple", &appleValue));
65 REQUIRE(appleValue == 3);
66
67 long long plumValue;
68 REQUIRE(settings.Write("plum", std::numeric_limits<long long>::max()));
69 REQUIRE(settings.Read("plum", &plumValue));
70 REQUIRE(plumValue == std::numeric_limits<long long>::max());
71
72 double pearValue;
73 REQUIRE(settings.Write("pear", std::numeric_limits<double>::epsilon()));
74 REQUIRE(settings.Read("pear", &pearValue));
75 REQUIRE(std::abs(pearValue - std::numeric_limits<double>::epsilon()) <= 0.001);
76
77 wxString pineappleValue;
78 REQUIRE(settings.Write("pineapple", "Lorem Ipsum"));
79 REQUIRE(settings.Read("pineapple", &pineappleValue));
80 REQUIRE(pineappleValue == "Lorem Ipsum");
81
82 Stringifyable mangoValue{0};
83 REQUIRE(settings.Write("mango", Stringifyable{ 1431655765 }));
84 REQUIRE(settings.Read("mango", &mangoValue));
85 REQUIRE(mangoValue.value == 1431655765);
86
87 REQUIRE(settings.Read("orange", &orangeValue, false));
88 REQUIRE(orangeValue == true);
89 REQUIRE(settings.Read("apple", &appleValue, 1000));
90 REQUIRE(appleValue == 3);
91 REQUIRE(settings.Read("plum", &plumValue, 2000LL));
92 REQUIRE(plumValue == std::numeric_limits<long long>::max());
93 REQUIRE(settings.Read("pear", &pearValue, 3000.0));
94 REQUIRE(std::abs(pearValue - std::numeric_limits<double>::epsilon()) <= 0.001);
95 REQUIRE(settings.Read("pineapple", &pineappleValue, { }));
96 REQUIRE(pineappleValue == "Lorem Ipsum");
97
98 bool orange1;
99 REQUIRE(!settings.Read("orange1", &orange1, orangeValue));
100 REQUIRE(orange1 == orangeValue);
101 int apple1;
102 REQUIRE(!settings.Read("apple1", &apple1, appleValue));
103 REQUIRE(apple1 == appleValue);
104 long long plum1;
105 REQUIRE(!settings.Read("plum1", &plum1, plumValue));
106 REQUIRE(plum1 == plumValue);
107 double pear1;
108 REQUIRE(!settings.Read("pear1", &pear1, pearValue));
109 REQUIRE(std::abs(pearValue - pear1) <= 0.001);
110 wxString pineapple1;
111 REQUIRE(!settings.Read("pineapple1", &pineapple1, pineappleValue));
112 REQUIRE(pineapple1 == pineappleValue);
113 Stringifyable mango1;
114 REQUIRE(!settings.Read("mango1", &mango1, mangoValue));
115 REQUIRE(mango1 == mangoValue);
116
117 REQUIRE(settings.Read("pineapple") == pineappleValue);
118 REQUIRE(settings.Read("pineapp").IsEmpty());
119 REQUIRE(settings.Read("pineapp", "not found") == "not found");
120 REQUIRE(settings.Read("pineapp", L"not found") == L"not found");
121
122 REQUIRE(settings.Read("orange", false) == orangeValue);
123 REQUIRE(settings.Read("apple", 0) == appleValue);
124 REQUIRE(settings.Read("plum", 0LL) == plumValue);
125 REQUIRE(settings.Read("pear", 0.0) == pearValue);
126 REQUIRE(settings.Read("mango", Stringifyable{-1}) == mangoValue);
127
128 REQUIRE(settings.Write("moon", "full"));
129 REQUIRE(settings.Read("moon") == "full");
130
131 REQUIRE(settings.Write("star", L"yellow"));
132 REQUIRE(settings.Read("star") == L"yellow");
133}
134
136{
137 settings.Clear();
138 REQUIRE(settings.GetGroup().empty());
139 REQUIRE(settings.GetChildKeys().empty());
140 REQUIRE(settings.GetChildGroups().empty());
141
142 settings.Write("apple", 10);
143 settings.Write("orange", true);
144
145 REQUIRE(settings.HasEntry("apple"));
146
147 REQUIRE(IsSame(settings.GetChildKeys(), { "orange", "apple" }));
148
149 {
150 //Create child group, and make sure path has switched to that group
151 auto group = settings.BeginGroup("group");
152 REQUIRE(settings.GetGroup() == "group");
153 REQUIRE(settings.GetChildKeys().empty());
154 REQUIRE(settings.GetChildGroups().empty());
155 }
156 //Exit the scope and restore previous path
157 REQUIRE(settings.GetGroup().empty());
158 REQUIRE(IsSame(settings.GetChildGroups(), { "group" }));
159 REQUIRE(settings.HasGroup("group"));
160
161 //Values could be read from/written to the child group without
162 //entering them explicitly
163 REQUIRE(settings.Write("path/to/variable", 7));
164 REQUIRE(IsSame(settings.GetChildGroups(), { "group", "path" }));
165 REQUIRE(settings.HasEntry("path/to/variable"));
166 REQUIRE(settings.HasGroup("path"));
167 REQUIRE(settings.HasGroup("path/to"));
168 REQUIRE(!settings.HasGroup("path/to/variable"));
169 REQUIRE(settings.Read("path/to/variable", 0) == 7);
170
171 {
172 auto group = settings.BeginGroup("group");
173 {
174 auto subgroup = settings.BeginGroup("subgroup");
175 REQUIRE(settings.GetGroup() == "group/subgroup");
176 REQUIRE(settings.Write("number", 4));
177 }
178 REQUIRE(settings.GetGroup() == "group");
179 REQUIRE(IsSame(settings.GetChildGroups(), { "subgroup" }));
180
181 REQUIRE(settings.Write("parrot/color", "red"));
182 REQUIRE(IsSame(settings.GetChildGroups(), { "subgroup", "parrot" }));
183
184 //Remove one of two subgroups
185 REQUIRE(settings.Remove("subgroup"));
186 REQUIRE(IsSame(settings.GetChildGroups(), { "parrot" }));
187
188 REQUIRE(settings.Write("guess", 42));
189 REQUIRE(IsSame(settings.GetChildKeys(), { "guess" }));
190 //Clear all child groups and values within the current group
191 REQUIRE(settings.Remove({}));
192 REQUIRE(settings.GetGroup() == "group");
193 REQUIRE(settings.GetChildGroups().empty());
194 REQUIRE(settings.GetChildKeys().empty());
195 }
196 REQUIRE(IsSame(settings.GetChildGroups(), { "group", "path" }));
197 REQUIRE(settings.GetGroup().IsEmpty());
198
199 //Using absolute path's
200 {
201 auto group1 = settings.BeginGroup("group1");
202 REQUIRE(settings.GetGroup() == "group1");
203
204 auto group2 = settings.BeginGroup("group2");
205 REQUIRE(settings.GetGroup() == "group1/group2");
206
207 {
208 auto group3 = settings.BeginGroup("/group3");
209 REQUIRE(settings.GetGroup() == "group3");
210
211 REQUIRE(settings.HasGroup("/group1/group2"));
212 REQUIRE(!settings.HasGroup("/group1/group3"));
213
214 REQUIRE(settings.Write("/group1/value", 1));
215 REQUIRE(settings.GetGroup() == "group3");
216 REQUIRE(settings.Read("/group1/value", 0) == 1);
217 REQUIRE(settings.HasEntry("/group1/value"));
218
219 REQUIRE(settings.Exists("/group1/value"));
220 REQUIRE(settings.Exists("/group1"));
221 }
222 REQUIRE(settings.GetGroup() == "group1/group2");
223 }
224
225 settings.Clear();
226 REQUIRE(settings.GetChildKeys().empty());
227 REQUIRE(settings.GetChildGroups().empty());
228}
#define str(a)
bool IsSame(const wxArrayString &arr, std::initializer_list< wxString > list, bool compareWithCase=true)
void TestRW(audacity::BasicSettings &settings)
void TestGroups(audacity::BasicSettings &settings)
wxString wxToString(const Stringifyable &obj)
bool wxFromString(const wxString &str, Stringifyable *obj)
static Settings & settings()
Definition: TrackInfo.cpp:51
Base class for objects that provide facility to store data persistently, and access it with string ke...
Definition: BasicSettings.h:31
bool operator==(const Stringifyable &other) const