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