]> git.mxchange.org Git - simgear.git/blob - simgear/props/propertyObject_test.cxx
Overload Rect::contains and add compound assignment operators to PropertyObject
[simgear.git] / simgear / props / propertyObject_test.cxx
1 #ifdef HAVE_CONFIG_H
2 #  include <simgear_config.h>
3 #endif
4
5 #ifdef NDEBUG
6 // Always enable DEBUG mode in test application, otherwise "assert" test
7 // statements have no effect and don't actually test anything (catch 17 ;-) ).
8 #undef NDEBUG
9 #endif
10
11 #include <simgear/compiler.h>
12
13 #include <iostream>
14 #include <cassert>
15 #include <cstdlib>
16 #include <cstring>
17
18 #include "propertyObject.hxx"
19
20 #include <simgear/structure/exception.hxx>
21
22 using std::cout;
23 using std::cerr;
24 using std::endl;
25
26 using namespace simgear;
27
28
29 SGPropertyNode* testRoot = NULL;
30
31 bool testBasic()
32 {
33   PropertyObject<int> aBar("a/bar");
34   assert(aBar == 1234);
35
36
37   PropertyObject<int> aWib("a/wib"); // doesn't exist
38   aWib = 999; // create + set
39   assert(aWib == 999); // read back
40   assert(testRoot->getIntValue("a/wib") == 999);
41
42   assert(aWib < 1000);
43   assert(998 < aWib);
44
45   PropertyObject<double> aFoo("a/foo");
46   assert(aFoo == 12.0);
47
48   double ff(aFoo);
49   assert(ff == 12.0); // comparison with literal
50   if (ff != 12.0) cout << "Error: a/foo != 12!" << endl;
51   
52   const float fff(12.0f);
53   assert(fff == aFoo); // comparion with float value
54   if (fff != aFoo) cout << "Error: 12 != a/foo" << endl;
55
56   return true;
57 }
58
59 void testRelative()
60 {
61   SGPropertyNode* n = testRoot->getNode("a");
62   assert(n);
63
64   PropertyObject<int> a1(n, "bar");
65   assert(a1 == 1234);
66
67   PropertyObject<int> a5(n, "some/child/path");
68   a5 = 4321;
69   assert(n->getIntValue("some/child/path") == 4321);
70
71   SGPropertyNode* m = testRoot->getNode("a/alice");
72   PropertyObject<std::string> a4(m);
73   assert(a4 == "aaaa");
74 }
75
76 void testString()
77 {
78   PropertyObject<std::string> sp("a/alice");
79   assert(sp == "aaaa"); // read
80
81   sp = "xxxx"; // assignment from char* literal
82   assert(!strcmp(testRoot->getStringValue("a/alice"), "xxxx"));
83
84   std::string d = "yyyy";
85   sp = d; // assignment from std::string
86   assert(sp == d);  // comaprisom with std::string
87
88   std::string e(sp), f; // check construction-conversion
89   assert(e == "yyyy");
90   f = sp; // assignment conversion
91   assert(f == "yyyy");
92 }
93
94 void testAssignment()
95 {
96   PropertyObject<int> a1("a/bar");
97   PropertyObject<int> a2("b/blah/foo[1]");
98
99  // ensure assignment between property objects copies values, *not*
100  // copies the property reference
101   a2 = a1 = 88; // a2 should *not* point to a/bar after this!
102   assert(testRoot->getIntValue("b/blah/foo[1]") == 88);
103   assert(a2.node() == testRoot->getNode("b/blah/foo[1]"));
104   a2 = 99;
105   assert(a2 == 99);
106   assert(a1 == 88);
107
108   PropertyObject<int> a3(a1);
109   assert(a1.node() == a3.node());
110   a3 = 44;
111   assert(a1 == 44);
112
113   // Compound assignment ops
114   a1 *= 2;
115   assert(a1 == 88);
116   a1 /= 2;
117   assert(a1 == 44);
118   a1 += 2;
119   assert(a1 == 46);
120   a1 -= 16;
121   assert(a1 == 30);
122   a1 %= 28;
123   assert(a1 == 2);
124   a1 >>= 1;
125   assert(a1 == 1);
126   a1 <<= 2;
127   assert(a1 == 4);
128   a1 &= 1;
129   assert(a1 == 0);
130   a1 ^= 2;
131   assert(a1 == 2);
132   a1 |= 1;
133   assert(a1 == 3);
134 }
135
136 void testSTLContainer()
137 {
138   std::vector<PropertyObject<int> > vec;
139 // enlarging the vec causes the copy-constructor to be called,
140 // when the storage is re-sized
141   vec.push_back(PropertyObject<int>("a/thing[0]")); 
142   vec.push_back(PropertyObject<int>("a/thing[1]")); 
143   vec.push_back(PropertyObject<int>("a/thing[2]")); 
144   vec.push_back(PropertyObject<int>("a/thing[3]")); 
145
146   vec[0] = 1234;
147   vec[1] = 2345;
148   vec[2] = 6789;
149   vec[3] = -11;
150
151   assert(testRoot->getIntValue("a/thing[2]") == 6789);
152   assert(testRoot->getIntValue("a/thing[3]") == -11);
153   assert(testRoot->getIntValue("a/thing[0]") == 1234);
154
155   for (int i=0; i<100; ++i) {
156     char path[128];
157     ::snprintf(path, 128, "d/foo[%d]", i);
158     vec.push_back(PropertyObject<int>(path));
159     testRoot->setIntValue(path, i * 4);
160   }
161
162   assert(vec[0] == 1234);
163   assert(vec[3] == -11);
164 }
165
166 void testReadMissing()
167 {
168   PropertyObject<bool> b("not/found/honest");
169
170   try {
171     bool v = b;
172     assert(false && "read of missing property didn't throw");
173     (void) v; // don't warn about unused variable
174   } catch (sg_exception& e) {
175     // expected
176   }
177
178   PropertyObject<std::string> s("also/missing");
179   try {
180     std::string s2 = s;
181   } catch (sg_exception& e) {
182     // expected
183   }
184 }
185
186 void testCreate()
187 {
188   PropertyObject<bool> a = PropertyObject<bool>::create("a/lemon", true);
189   assert(a == true);
190   assert(testRoot->getBoolValue("a/lemon") == true);
191   
192
193   PropertyObject<int> b(PropertyObject<int>::create("a/pear", 3142));
194   assert(b == 3142);
195   
196   PropertyObject<std::string> c(PropertyObject<std::string>::create("a/lime", "fofofo"));
197   assert(c == "fofofo");
198
199 // check overloads for string version
200   SGPropertyNode* n = testRoot->getNode("b", true);
201   PropertyObject<std::string> d(PropertyObject<std::string>::create(n, "grape", "xyz"));
202   assert(!strcmp(testRoot->getStringValue("b/grape"), "xyz"));
203   
204   
205 }
206
207 int main(int argc, char* argv[])
208 {
209         testRoot = new SGPropertyNode();
210         simgear::PropertyObjectBase::setDefaultRoot(testRoot);
211
212 // create some properties 'manually'
213         testRoot->setDoubleValue("a/foo", 12.0);
214         testRoot->setIntValue("a/bar", 1234);
215         testRoot->setBoolValue("a/flags[3]", true);
216   testRoot->setStringValue("a/alice", "aaaa");
217
218 // basic reading / setting
219         if (!testBasic()) {
220                 return EXIT_FAILURE;            
221         }
222
223   testRelative();
224   testReadMissing();
225   testString();
226   testAssignment();
227   testSTLContainer();
228   testCreate();
229
230   return EXIT_SUCCESS;
231 }
232