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