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