1 // Copyright 2008, Google Inc. All rights reserved.
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are met:
5 //
6 //  1. Redistributions of source code must retain the above copyright notice,
7 //     this list of conditions and the following disclaimer.
8 //  2. Redistributions in binary form must reproduce the above copyright notice,
9 //     this list of conditions and the following disclaimer in the documentation
10 //     and/or other materials provided with the distribution.
11 //  3. Neither the name of Google Inc. nor the names of its contributors may be
12 //     used to endorse or promote products derived from this software without
13 //     specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
18 // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 // This file contains the unit tests for Coordinates, Geometry, Point,
27 // LineString, LinearRing, Polygon, InnerBoundaryIs, OuterBoundaryIs, and
28 // MultiGeometry.
29 
30 #include "kml/dom/geometry.h"
31 #include "kml/dom/kml_cast.h"
32 #include "kml/dom/kml_factory.h"
33 #include "kml/dom/kml_ptr.h"
34 #include "kml/dom/kml_funcs.h"
35 #include "kml/dom/serializer.h"
36 #include "gtest/gtest.h"
37 
38 using kmlbase::Vec3;
39 
40 namespace kmldom {
41 
42 // Test Coordinates.
43 class CoordinatesTest : public testing::Test {
44  protected:
SetUp()45   virtual void SetUp() {
46     coordinates_ = KmlFactory::GetFactory()->CreateCoordinates();
47   }
48 
49   CoordinatesPtr coordinates_;
50 };
51 
TEST_F(CoordinatesTest,TestType)52 TEST_F(CoordinatesTest, TestType) {
53   ASSERT_EQ(Type_coordinates, coordinates_->Type());
54   ASSERT_TRUE(coordinates_->IsA(Type_coordinates));
55 }
56 
57 // Verify proper defaults:
TEST_F(CoordinatesTest,TestDefaults)58 TEST_F(CoordinatesTest, TestDefaults) {
59   ASSERT_EQ(static_cast<size_t>(0), coordinates_->get_coordinates_array_size());
60 }
61 
62 // Verify the add_latlng() setter.
TEST_F(CoordinatesTest,TestAddLatLng)63 TEST_F(CoordinatesTest, TestAddLatLng) {
64   const double kLat(-22.22);
65   const double kLon(44.44);
66   coordinates_->add_latlng(kLat, kLon);
67   ASSERT_EQ(static_cast<size_t>(1),
68             coordinates_->get_coordinates_array_size());
69   Vec3 vec3 = coordinates_->get_coordinates_array_at(0);
70   ASSERT_DOUBLE_EQ(kLat, vec3.get_latitude());
71   ASSERT_DOUBLE_EQ(kLon, vec3.get_longitude());
72   ASSERT_FALSE(vec3.has_altitude());
73   ASSERT_DOUBLE_EQ(0.0, vec3.get_altitude());
74 }
75 
76 // Verify the add_latlngalt() setter.
TEST_F(CoordinatesTest,TestAddLatLngAlt)77 TEST_F(CoordinatesTest, TestAddLatLngAlt) {
78   const double kLat(-22.22);
79   const double kLon(44.44);
80   const double kAlt(10001.2002);
81   coordinates_->add_latlngalt(kLat, kLon, kAlt);
82   ASSERT_EQ(static_cast<size_t>(1),
83             coordinates_->get_coordinates_array_size());
84   Vec3 vec3 = coordinates_->get_coordinates_array_at(0);
85   ASSERT_DOUBLE_EQ(kLat, vec3.get_latitude());
86   ASSERT_DOUBLE_EQ(kLon, vec3.get_longitude());
87   ASSERT_TRUE(vec3.has_altitude());
88   ASSERT_DOUBLE_EQ(kAlt, vec3.get_altitude());
89 }
90 
91 // Verify the add_vec3() setter.
TEST_F(CoordinatesTest,TestAddVec3)92 TEST_F(CoordinatesTest, TestAddVec3) {
93   const double kLat(-22.22);
94   const double kLon(44.44);
95   const double kAlt(10001.2002);
96   Vec3 v(kLon, kLat, kAlt);
97   coordinates_->add_vec3(v);
98   ASSERT_EQ(static_cast<size_t>(1),
99             coordinates_->get_coordinates_array_size());
100   Vec3 vec3_0 = coordinates_->get_coordinates_array_at(0);
101   ASSERT_DOUBLE_EQ(kLat, vec3_0.get_latitude());
102   ASSERT_DOUBLE_EQ(kLon, vec3_0.get_longitude());
103   ASSERT_TRUE(vec3_0.has_altitude());
104   ASSERT_DOUBLE_EQ(kAlt, vec3_0.get_altitude());
105 
106   coordinates_->add_vec3(Vec3());
107   ASSERT_EQ(static_cast<size_t>(2),
108             coordinates_->get_coordinates_array_size());
109   Vec3 vec3_1 = coordinates_->get_coordinates_array_at(1);
110   ASSERT_DOUBLE_EQ(0.0, vec3_1.get_latitude());
111   ASSERT_DOUBLE_EQ(0.0, vec3_1.get_longitude());
112   ASSERT_DOUBLE_EQ(0.0, vec3_1.get_altitude());
113 
114   coordinates_->add_vec3(Vec3(kLon, kLat));
115   ASSERT_EQ(static_cast<size_t>(3),
116             coordinates_->get_coordinates_array_size());
117   Vec3 vec3_2 = coordinates_->get_coordinates_array_at(2);
118   ASSERT_DOUBLE_EQ(kLat, vec3_2.get_latitude());
119   ASSERT_DOUBLE_EQ(kLon, vec3_2.get_longitude());
120   ASSERT_DOUBLE_EQ(0.0, vec3_2.get_altitude());
121 }
122 
123 // Verify a bunch of points in a <coordinates> element.
TEST_F(CoordinatesTest,TestAddLatLngAltMany)124 TEST_F(CoordinatesTest, TestAddLatLngAltMany) {
125   const size_t kNumPoints(1001);
126   size_t i;
127   for (i = 0; i < kNumPoints; ++i) {
128     coordinates_->add_latlngalt(static_cast<double>(i % 90),
129                                 static_cast<double>(i % 180),
130                                 static_cast<double>(i));
131   }
132   ASSERT_EQ(static_cast<size_t>(kNumPoints),
133             coordinates_->get_coordinates_array_size());
134   for (i = 0; i < kNumPoints; ++i) {
135     Vec3 vec3 = coordinates_->get_coordinates_array_at(i);
136     ASSERT_DOUBLE_EQ(static_cast<double>(i % 90), vec3.get_latitude());
137     ASSERT_DOUBLE_EQ(static_cast<double>(i % 180), vec3.get_longitude());
138     ASSERT_TRUE(vec3.has_altitude());
139     ASSERT_DOUBLE_EQ(static_cast<double>(i), vec3.get_altitude());
140   }
141 }
142 
TEST_F(CoordinatesTest,TestParseVec3WithAltitude)143 TEST_F(CoordinatesTest, TestParseVec3WithAltitude) {
144   const char* basic_3d_point = "1.123,-2.789,3000.5919";
145   char *endp;
146   Vec3 vec;
147   ASSERT_TRUE(Coordinates::ParseVec3(basic_3d_point, &endp, &vec));
148   ASSERT_DOUBLE_EQ(-2.789, vec.get_latitude());
149   ASSERT_DOUBLE_EQ(1.123, vec.get_longitude());
150   ASSERT_TRUE(vec.has_altitude());
151   ASSERT_DOUBLE_EQ(3000.5919, vec.get_altitude());
152   ASSERT_EQ(basic_3d_point + strlen(basic_3d_point), endp);
153 
154   const char* basic_3d_line = "-122.123,38.789,1050.0987 "
155                               "-122.123,39.789,1050.098";
156   ASSERT_TRUE(Coordinates::ParseVec3(basic_3d_line, &endp, &vec));
157   ASSERT_DOUBLE_EQ(38.789, vec.get_latitude());
158   ASSERT_DOUBLE_EQ(-122.123, vec.get_longitude());
159   ASSERT_TRUE(vec.has_altitude());
160   ASSERT_DOUBLE_EQ(1050.0987, vec.get_altitude());
161   ASSERT_TRUE(Coordinates::ParseVec3(endp, &endp, &vec));
162   ASSERT_DOUBLE_EQ(39.789, vec.get_latitude());
163   ASSERT_DOUBLE_EQ(-122.123, vec.get_longitude());
164   ASSERT_TRUE(vec.has_altitude());
165   ASSERT_DOUBLE_EQ(1050.098, vec.get_altitude());
166 }
167 
TEST_F(CoordinatesTest,TestParseVec3NoAltitude)168 TEST_F(CoordinatesTest, TestParseVec3NoAltitude) {
169   const char* basic_2d_point = "10.10,-20.20";
170   char *endp;
171   Vec3 vec;
172   ASSERT_TRUE(Coordinates::ParseVec3(basic_2d_point, &endp, &vec));
173   ASSERT_DOUBLE_EQ(-20.20, vec.get_latitude());
174   ASSERT_DOUBLE_EQ(10.10, vec.get_longitude());
175   ASSERT_FALSE(vec.has_altitude());
176   ASSERT_DOUBLE_EQ(0.0, vec.get_altitude());
177 
178   const char* point2d_with_1space = "15.10, -24.20";
179   ASSERT_TRUE(Coordinates::ParseVec3(point2d_with_1space, &endp, &vec));
180   ASSERT_DOUBLE_EQ(-24.20, vec.get_latitude());
181   ASSERT_DOUBLE_EQ(15.10, vec.get_longitude());
182   ASSERT_FALSE(vec.has_altitude());
183   ASSERT_DOUBLE_EQ(0.0, vec.get_altitude());
184 
185   const char* point2d_with_2spaces = "15.11 , -24.25";
186   ASSERT_TRUE(Coordinates::ParseVec3(point2d_with_2spaces, &endp, &vec));
187   ASSERT_DOUBLE_EQ(-24.25, vec.get_latitude());
188   ASSERT_DOUBLE_EQ(15.11, vec.get_longitude());
189   ASSERT_FALSE(vec.has_altitude());
190   ASSERT_DOUBLE_EQ(0.0, vec.get_altitude());
191 
192   const char* basic_2d_line = "122.123,-38.789 "
193                               "122.123,-39.789";
194   ASSERT_TRUE(Coordinates::ParseVec3(basic_2d_line, &endp, &vec));
195   ASSERT_DOUBLE_EQ(-38.789, vec.get_latitude());
196   ASSERT_DOUBLE_EQ(122.123, vec.get_longitude());
197   ASSERT_FALSE(vec.has_altitude());
198   ASSERT_DOUBLE_EQ(0.0, vec.get_altitude());
199   ASSERT_TRUE(Coordinates::ParseVec3(endp, &endp, &vec));
200   ASSERT_DOUBLE_EQ(-39.789, vec.get_latitude());
201   ASSERT_DOUBLE_EQ(122.123, vec.get_longitude());
202   ASSERT_FALSE(vec.has_altitude());
203   ASSERT_DOUBLE_EQ(0.0, vec.get_altitude());
204 
205   // How our own serializer emits <coordinates>
206   const char* line_with_newlines = "\n"
207                                    "  -160.073803556017,22.0041773078075\n"
208                                    "  -160.121962433575,21.9639787234984\n"
209                                    "  -160.22633646805,21.8915919620539\n"
210                                    "  ";
211   ASSERT_TRUE(Coordinates::ParseVec3(line_with_newlines, &endp, &vec));
212 
213   const char* exponential_2d_pt = "1E-02, 2E-02";  // 0.01, 0.02
214   ASSERT_TRUE(Coordinates::ParseVec3(exponential_2d_pt, &endp, &vec));
215   ASSERT_DOUBLE_EQ(0.02, vec.get_latitude());
216   ASSERT_DOUBLE_EQ(0.01, vec.get_longitude());
217   ASSERT_FALSE(vec.has_altitude());
218   ASSERT_DOUBLE_EQ(0.0, vec.get_altitude());
219 
220   // Ensure junk data is handled gracefully.
221   const char* junk_coords1 = "this will not parse correctly";
222   ASSERT_FALSE(Coordinates::ParseVec3(junk_coords1, &endp, &vec));
223 
224   const char* junk_coords2 = "0,foo";  // Will parse successfully.
225   ASSERT_TRUE(Coordinates::ParseVec3(junk_coords2, &endp, &vec));
226   ASSERT_DOUBLE_EQ(0.0, vec.get_latitude());
227   ASSERT_DOUBLE_EQ(0.0, vec.get_longitude());
228   ASSERT_FALSE(vec.has_altitude());
229   ASSERT_DOUBLE_EQ(0.0, vec.get_altitude());
230 
231   const char* junk_coords3 = "bar,0";  // Will parse successfully.
232   ASSERT_TRUE(Coordinates::ParseVec3(junk_coords3, &endp, &vec));
233   ASSERT_DOUBLE_EQ(0.0, vec.get_latitude());
234   ASSERT_DOUBLE_EQ(0.0, vec.get_longitude());
235   ASSERT_FALSE(vec.has_altitude());
236   ASSERT_DOUBLE_EQ(0.0, vec.get_altitude());
237 
238   const char* junk_coords4 = "\n";  // Will fail parsing.
239   ASSERT_FALSE(Coordinates::ParseVec3(junk_coords4, &endp, &vec));
240 }
241 
TEST_F(CoordinatesTest,TestParsePoint)242 TEST_F(CoordinatesTest, TestParsePoint) {
243   // Parser gathers character data and sets element
244   coordinates_->Parse("1.1,-2.2,3.3");
245   ASSERT_EQ(static_cast<size_t>(1), coordinates_->get_coordinates_array_size());
246   Vec3 vec = coordinates_->get_coordinates_array_at(0);
247   ASSERT_DOUBLE_EQ(-2.2, vec.get_latitude());
248   ASSERT_DOUBLE_EQ(1.1, vec.get_longitude());
249   ASSERT_TRUE(vec.has_altitude());
250   ASSERT_DOUBLE_EQ(3.3, vec.get_altitude());
251 }
252 
TEST_F(CoordinatesTest,TestParseLine)253 TEST_F(CoordinatesTest, TestParseLine) {
254   // Parser gathers character data and sets element
255   coordinates_->Parse("1.1,-2.2,3.3 -5.1,32.9872,10000.3");
256   ASSERT_EQ(static_cast<size_t>(2), coordinates_->get_coordinates_array_size());
257   ASSERT_DOUBLE_EQ(-2.2,
258                    coordinates_->get_coordinates_array_at(0).get_latitude());
259   ASSERT_DOUBLE_EQ(1.1,
260                    coordinates_->get_coordinates_array_at(0).get_longitude());
261   ASSERT_TRUE(coordinates_->get_coordinates_array_at(0).has_altitude());
262   ASSERT_DOUBLE_EQ(3.3,
263                    coordinates_->get_coordinates_array_at(0).get_altitude());
264 }
265 
TEST_F(CoordinatesTest,TestParseBadSeparator)266 TEST_F(CoordinatesTest, TestParseBadSeparator) {
267   // Ensure graceful handling of bad data.
268   coordinates_->Parse("130.999*66.56083,75");
269   ASSERT_EQ(static_cast<size_t>(1), coordinates_->get_coordinates_array_size());
270   ASSERT_DOUBLE_EQ(75.0,
271                    coordinates_->get_coordinates_array_at(0).get_latitude());
272   ASSERT_DOUBLE_EQ(130.999,
273                    coordinates_->get_coordinates_array_at(0).get_longitude());
274   ASSERT_DOUBLE_EQ(0.0,
275                    coordinates_->get_coordinates_array_at(0).get_altitude());
276 }
277 
TEST_F(CoordinatesTest,TestClear)278 TEST_F(CoordinatesTest, TestClear) {
279   // Clearing nothing results in nothing.
280   coordinates_->Clear();
281   ASSERT_EQ(static_cast<size_t>(0), coordinates_->get_coordinates_array_size());
282   // Clearing one thing results in nothing.
283   coordinates_->add_latlng(1,2);
284   ASSERT_EQ(static_cast<size_t>(1), coordinates_->get_coordinates_array_size());
285   coordinates_->Clear();
286   ASSERT_EQ(static_cast<size_t>(0), coordinates_->get_coordinates_array_size());
287   // Clearing many things results in nothing.
288   const size_t kCount(1001);
289   for (size_t i = 0; i < kCount; ++i) {
290     coordinates_->add_latlngalt(i,i,i);
291   }
292   ASSERT_EQ(kCount, coordinates_->get_coordinates_array_size());
293   coordinates_->Clear();
294   ASSERT_EQ(static_cast<size_t>(0), coordinates_->get_coordinates_array_size());
295 }
296 
297 // This typedef is a convenience for use with the CoordinatesSerializerStub.
298 typedef std::vector<kmlbase::Vec3> Vec3Vector;
299 
300 // This class provides a mock Serializer specifically designed to capture
301 // the output of the Coordinates::Serialize() method.  Serialization of
302 // <coordinates> follows a pattern no other KML element follows (it's a
303 // simple element as far as XML is concerned, but the content does follow a
304 // structure with its repeated coordinates tuples.
305 class MockCoordinatesSerializer : public Serializer {
306  public:
307   // The MockCoordinatesSerializer appends each Vec3 emitted by the
308   // coordinates serialize method.  It is up to the caller to ensure that the
309   // vector is in the desired state before using this class (empty, for
310   // example).
MockCoordinatesSerializer(Vec3Vector * vec3_vector)311   MockCoordinatesSerializer(Vec3Vector* vec3_vector)
312     : vec3_vector_(vec3_vector),
313       element_count_(0) {
314   }
315   // Each tuple in the <coordinates> content is emitted as a kmlbase::Vec3.
SaveVec3(const kmlbase::Vec3 & vec3)316   virtual void SaveVec3(const kmlbase::Vec3& vec3) {
317     vec3_vector_->push_back(vec3);
318   }
319   // This is called once before the Vec3's are emitted.
BeginElementArray(int type_id,size_t element_count)320   virtual void BeginElementArray(int type_id, size_t element_count) {
321     element_count_ += static_cast<int>(element_count);
322   }
323   // This is called once after all Vec3's are emitted.
EndElementArray(int type_id)324   virtual void EndElementArray(int type_id) {}
get_element_count() const325   int get_element_count() const {
326     return element_count_;
327   }
328  private:
329   Vec3Vector* vec3_vector_;
330   int element_count_;
331 };
332 
333 // Test serialization of <coordinates/>
TEST_F(CoordinatesTest,TestSerializeNone)334 TEST_F(CoordinatesTest, TestSerializeNone) {
335   Vec3Vector vec3_vector;
336   MockCoordinatesSerializer mock(&vec3_vector);
337   // This calls Coordinates::Serialize().
338   mock.SaveElement(coordinates_);
339   ASSERT_TRUE(vec3_vector.empty());
340   ASSERT_EQ(0, mock.get_element_count());
341 }
342 
343 // Test serialization of <coordinates>1.1,2.2,3.3</coordinates>.
TEST_F(CoordinatesTest,TestSerializeOne)344 TEST_F(CoordinatesTest, TestSerializeOne) {
345   Vec3 vec3(1.1, 2.2, 3.3);
346   coordinates_->add_vec3(vec3);
347   Vec3Vector vec3_vector;
348   MockCoordinatesSerializer mock(&vec3_vector);
349   // This calls Coordinates::Serialize().
350   mock.SaveElement(coordinates_);
351   ASSERT_EQ(static_cast<size_t>(1), vec3_vector.size());
352   ASSERT_EQ(1, mock.get_element_count());
353   ASSERT_EQ(vec3.get_latitude(), vec3_vector[0].get_latitude());
354   ASSERT_EQ(vec3.get_longitude(), vec3_vector[0].get_longitude());
355   ASSERT_EQ(vec3.has_altitude(), vec3_vector[0].has_altitude());
356   ASSERT_EQ(vec3.get_altitude(), vec3_vector[0].get_altitude());
357 }
358 
359 // Test serialization of:
360 // <coordinates>0.2,0.1,0.3 1.2,1.1,1.3 2.2,2.1,2.3 ... </coordinates>/
TEST_F(CoordinatesTest,TestSerializeMany)361 TEST_F(CoordinatesTest, TestSerializeMany) {
362   const size_t kNumTuples = 47;
363   const double kLatFrac = 0.1;
364   const double kLngFrac = 0.2;
365   const double kAltFrac = 0.3;
366   for (size_t i = 0; i < kNumTuples; ++i) {
367     coordinates_->add_latlngalt(i + kLatFrac, i + kLngFrac, i + kAltFrac);
368   }
369   Vec3Vector vec3_vector;
370   MockCoordinatesSerializer mock(&vec3_vector);
371   // This calls Coordinates::Serialize().
372   mock.SaveElement(coordinates_);
373   ASSERT_EQ(kNumTuples, vec3_vector.size());
374   ASSERT_EQ(static_cast<int>(kNumTuples), mock.get_element_count());
375   for (size_t i = 0; i < kNumTuples; ++i) {
376     ASSERT_EQ(i + kLatFrac, vec3_vector[i].get_latitude());
377     ASSERT_EQ(i + kLngFrac, vec3_vector[i].get_longitude());
378     ASSERT_TRUE(vec3_vector[i].has_altitude());
379     ASSERT_EQ(i + kAltFrac, vec3_vector[i].get_altitude());
380   }
381 }
382 
383 // Coordinate tuples must be separated by a space. However, the world is
384 // imperfect and thus we try to do the right thing with this:
385 // <coordinates>1,2,3,4,5,6,7,8,9</coordinates>, where the "right thing" is
386 // to take it as three lng,lat,alt tuples. This is Google Earth's behavior.
TEST_F(CoordinatesTest,TestCommaSeparators)387 TEST_F(CoordinatesTest, TestCommaSeparators) {
388   coordinates_->Parse("1,2,3,4,5,6,7,8,9");
389   ASSERT_EQ(static_cast<size_t>(3), coordinates_->get_coordinates_array_size());
390   ASSERT_DOUBLE_EQ(2.0,
391                    coordinates_->get_coordinates_array_at(0).get_latitude());
392   ASSERT_DOUBLE_EQ(1.0,
393                    coordinates_->get_coordinates_array_at(0).get_longitude());
394   ASSERT_DOUBLE_EQ(3.0,
395                    coordinates_->get_coordinates_array_at(0).get_altitude());
396   ASSERT_DOUBLE_EQ(5.0,
397                    coordinates_->get_coordinates_array_at(1).get_latitude());
398   ASSERT_DOUBLE_EQ(4.0,
399                    coordinates_->get_coordinates_array_at(1).get_longitude());
400   ASSERT_DOUBLE_EQ(6.0,
401                    coordinates_->get_coordinates_array_at(1).get_altitude());
402   ASSERT_DOUBLE_EQ(8.0,
403                    coordinates_->get_coordinates_array_at(2).get_latitude());
404   ASSERT_DOUBLE_EQ(7.0,
405                    coordinates_->get_coordinates_array_at(2).get_longitude());
406   ASSERT_DOUBLE_EQ(9.0,
407                    coordinates_->get_coordinates_array_at(2).get_altitude());
408 }
409 
410 // Test Point.
411 class PointTest : public testing::Test {
412  protected:
SetUp()413   virtual void SetUp() {
414     point_ = KmlFactory::GetFactory()->CreatePoint();
415   }
416 
417   PointPtr point_;
418 };
419 
TEST_F(PointTest,TestType)420 TEST_F(PointTest, TestType) {
421   ASSERT_EQ(Type_Point, point_->Type());
422   ASSERT_TRUE(point_->IsA(Type_Point));
423   ASSERT_TRUE(point_->IsA(Type_Geometry));
424   ASSERT_TRUE(point_->IsA(Type_Object));
425 }
426 
427 // Verify proper defaults:
TEST_F(PointTest,TestDefaults)428 TEST_F(PointTest, TestDefaults) {
429   ASSERT_FALSE(point_->has_id());
430   ASSERT_FALSE(point_->has_targetid());
431   ASSERT_FALSE(point_->has_extrude());
432   ASSERT_FALSE(point_->get_extrude());
433   ASSERT_FALSE(point_->has_altitudemode());
434   ASSERT_TRUE(ALTITUDEMODE_CLAMPTOGROUND == point_->get_altitudemode());
435   ASSERT_FALSE(point_->has_gx_altitudemode());
436   ASSERT_TRUE(GX_ALTITUDEMODE_CLAMPTOSEAFLOOR == point_->get_gx_altitudemode());
437   ASSERT_FALSE(point_->has_coordinates());
438   ASSERT_TRUE(NULL == point_->get_coordinates());
439 }
440 
441 // Verify setting default makes has_xxx() true:
TEST_F(PointTest,TestSetToDefaultValues)442 TEST_F(PointTest, TestSetToDefaultValues) {
443   point_->set_extrude(point_->get_extrude());
444   point_->set_altitudemode(point_->get_altitudemode());
445   point_->set_gx_altitudemode(point_->get_gx_altitudemode());
446   point_->set_coordinates(NULL);  // should not crash
447   ASSERT_TRUE(point_->has_extrude());
448   ASSERT_TRUE(point_->has_altitudemode());
449   ASSERT_TRUE(point_->has_gx_altitudemode());
450   ASSERT_FALSE(point_->has_coordinates());  // ptr is null
451 }
452 
453 // Verify set, get, has, clear:
TEST_F(PointTest,TestSetGetHasClear)454 TEST_F(PointTest, TestSetGetHasClear) {
455   // Non-default values:
456   bool extrude = true;
457   AltitudeModeEnum altitudemode = ALTITUDEMODE_RELATIVETOGROUND;
458   GxAltitudeModeEnum gx_altitudemode = GX_ALTITUDEMODE_RELATIVETOSEAFLOOR;
459   CoordinatesPtr coordinates = KmlFactory::GetFactory()->CreateCoordinates();
460   const char* id = "point-id";
461   const char* targetid = "point-targetid";
462 
463   // Set all fields:
464   point_->set_id(id);
465   point_->set_targetid(targetid);
466   point_->set_extrude(extrude);
467   point_->set_altitudemode(altitudemode);
468   point_->set_gx_altitudemode(gx_altitudemode);
469   point_->set_coordinates(coordinates);
470 
471   // Verify getter and has_xxx():
472   ASSERT_TRUE(point_->has_id());
473   ASSERT_EQ(id, point_->get_id());
474   ASSERT_TRUE(point_->has_targetid());
475   ASSERT_EQ(targetid, point_->get_targetid());
476   ASSERT_TRUE(point_->has_extrude());
477   ASSERT_EQ(extrude, point_->get_extrude());
478   ASSERT_TRUE(point_->has_altitudemode());
479   ASSERT_EQ(altitudemode, point_->get_altitudemode());
480   ASSERT_TRUE(point_->has_gx_altitudemode());
481   ASSERT_EQ(gx_altitudemode, point_->get_gx_altitudemode());
482   ASSERT_TRUE(point_->has_coordinates());
483   ASSERT_EQ(coordinates, point_->get_coordinates());
484 
485   // Clear all fields:
486   point_->clear_id();
487   point_->clear_targetid();
488   point_->clear_extrude();
489   point_->clear_altitudemode();
490   point_->clear_gx_altitudemode();
491   point_->clear_coordinates();
492 
493 }
494 
TEST_F(PointTest,TestSerialize)495 TEST_F(PointTest, TestSerialize) {
496   point_->set_id("point-id");
497   point_->set_extrude(true);
498   point_->set_coordinates(KmlFactory::GetFactory()->CreateCoordinates());
499   string expected(
500     "<Point id=\"point-id\">"
501     "<extrude>1</extrude>"
502     "<coordinates/>"
503     "</Point>"
504   );
505   ASSERT_EQ(expected, SerializeRaw(point_));
506 }
507 
TEST_F(PointTest,TestSerializeParseAll)508 TEST_F(PointTest, TestSerializeParseAll) {
509   point_->set_id("point-id");
510   point_->set_extrude(false);
511   point_->set_gx_altitudemode(GX_ALTITUDEMODE_RELATIVETOSEAFLOOR);
512   point_->set_coordinates(KmlFactory::GetFactory()->CreateCoordinates());
513   string expected(
514     "<Point id=\"point-id\">"
515     "<extrude>0</extrude>"
516     "<gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>"
517     "<coordinates/>"
518     "</Point>"
519   );
520   ASSERT_EQ(expected, SerializeRaw(point_));
521   string errors;
522   ElementPtr element = Parse(expected, &errors);
523   ASSERT_TRUE(element);
524   ASSERT_TRUE(errors.empty());
525   PointPtr point = AsPoint(element);
526   ASSERT_TRUE(point);
527   ASSERT_TRUE(point->has_id());
528   ASSERT_EQ(string("point-id"), point->get_id());
529   ASSERT_TRUE(point->has_extrude());
530   ASSERT_EQ(0, point->get_extrude());
531   ASSERT_FALSE(point->has_altitudemode());
532   ASSERT_TRUE(point->has_gx_altitudemode());
533   ASSERT_EQ(GX_ALTITUDEMODE_RELATIVETOSEAFLOOR, point->get_gx_altitudemode());
534 }
535 
536 // Test LineString.
537 class LineStringTest : public testing::Test {
538  protected:
SetUp()539   virtual void SetUp() {
540     linestring_ = KmlFactory::GetFactory()->CreateLineString();
541   }
542 
543   LineStringPtr linestring_;
544 };
545 
TEST_F(LineStringTest,TestType)546 TEST_F(LineStringTest, TestType) {
547   ASSERT_EQ(Type_LineString, linestring_->Type());
548   ASSERT_TRUE(linestring_->IsA(Type_LineString));
549   ASSERT_TRUE(linestring_->IsA(Type_Geometry));
550   ASSERT_TRUE(linestring_->IsA(Type_Object));
551 }
552 
553 // Verify proper defaults:
TEST_F(LineStringTest,TestDefaults)554 TEST_F(LineStringTest, TestDefaults) {
555   ASSERT_FALSE(linestring_->has_id());
556   ASSERT_FALSE(linestring_->has_targetid());
557   ASSERT_FALSE(linestring_->has_extrude());
558   ASSERT_FALSE(linestring_->get_extrude());
559   ASSERT_FALSE(linestring_->has_tessellate());
560   ASSERT_FALSE(linestring_->get_tessellate());
561   ASSERT_FALSE(linestring_->has_altitudemode());
562   ASSERT_EQ(ALTITUDEMODE_CLAMPTOGROUND, linestring_->get_altitudemode());
563   ASSERT_FALSE(linestring_->has_gx_altitudemode());
564   ASSERT_EQ(GX_ALTITUDEMODE_CLAMPTOSEAFLOOR,
565             linestring_->get_gx_altitudemode());
566   ASSERT_FALSE(linestring_->has_coordinates());
567 }
568 
569 // Verify setting default makes has_xxx() true:
TEST_F(LineStringTest,TestSetToDefaultValues)570 TEST_F(LineStringTest, TestSetToDefaultValues) {
571   linestring_->set_extrude(linestring_->get_extrude());
572   linestring_->set_tessellate(linestring_->get_tessellate());
573   linestring_->set_altitudemode(linestring_->get_altitudemode());
574   linestring_->set_gx_altitudemode(linestring_->get_gx_altitudemode());
575   linestring_->set_coordinates(NULL);  // should not crash
576   ASSERT_TRUE(linestring_->has_extrude());
577   ASSERT_TRUE(linestring_->has_tessellate());
578   ASSERT_TRUE(linestring_->has_altitudemode());
579   ASSERT_TRUE(linestring_->has_gx_altitudemode());
580   ASSERT_FALSE(linestring_->has_coordinates());  // ptr is null
581 }
582 
583 // Verify set, get, has, clear:
TEST_F(LineStringTest,TestSetGetHasClear)584 TEST_F(LineStringTest, TestSetGetHasClear) {
585   // Non-default values:
586   bool extrude = true;
587   bool tessellate = true;
588   AltitudeModeEnum altitudemode = ALTITUDEMODE_RELATIVETOGROUND;
589   GxAltitudeModeEnum gx_altitudemode = GX_ALTITUDEMODE_RELATIVETOSEAFLOOR;
590   CoordinatesPtr coordinates = KmlFactory::GetFactory()->CreateCoordinates();
591 
592   // Set all fields:
593   linestring_->set_extrude(extrude);
594   linestring_->set_tessellate(tessellate);
595   linestring_->set_altitudemode(altitudemode);
596   linestring_->set_gx_altitudemode(gx_altitudemode);
597   linestring_->set_coordinates(coordinates);
598 
599   // Verify getter and has_xxx():
600   ASSERT_TRUE(linestring_->has_extrude());
601   ASSERT_EQ(extrude, linestring_->get_extrude());
602   ASSERT_TRUE(linestring_->has_tessellate());
603   ASSERT_EQ(tessellate, linestring_->get_tessellate());
604   ASSERT_TRUE(linestring_->has_altitudemode());
605   ASSERT_EQ(altitudemode, linestring_->get_altitudemode());
606   ASSERT_TRUE(linestring_->has_gx_altitudemode());
607   ASSERT_EQ(gx_altitudemode, linestring_->get_gx_altitudemode());
608   ASSERT_TRUE(linestring_->has_coordinates());
609   ASSERT_EQ(coordinates, linestring_->get_coordinates());
610 
611   // Clear all fields:
612   linestring_->clear_extrude();
613   linestring_->clear_tessellate();
614   linestring_->clear_altitudemode();
615   linestring_->clear_gx_altitudemode();
616   linestring_->clear_coordinates();
617 }
618 
TEST_F(LineStringTest,TestSerialize)619 TEST_F(LineStringTest, TestSerialize) {
620   linestring_->set_id("linestring-id");
621   linestring_->set_tessellate(true);
622   linestring_->set_coordinates(KmlFactory::GetFactory()->CreateCoordinates());
623   string expected(
624     "<LineString id=\"linestring-id\">"
625     "<tessellate>1</tessellate>"
626     "<coordinates/>"
627     "</LineString>"
628   );
629   ASSERT_EQ(expected, SerializeRaw(linestring_));
630 }
631 
TEST_F(LineStringTest,TestSerializeParseAll)632 TEST_F(LineStringTest, TestSerializeParseAll) {
633   linestring_->set_id("linestring-id");
634   linestring_->set_extrude(true);
635   linestring_->set_tessellate(true);
636   linestring_->set_gx_altitudemode(GX_ALTITUDEMODE_RELATIVETOSEAFLOOR);
637   linestring_->set_coordinates(KmlFactory::GetFactory()->CreateCoordinates());
638   string expected(
639     "<LineString id=\"linestring-id\">"
640     "<extrude>1</extrude>"
641     "<tessellate>1</tessellate>"
642     "<gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>"
643     "<coordinates/>"
644     "</LineString>"
645   );
646   ASSERT_EQ(expected, SerializeRaw(linestring_));
647   string errors;
648   ElementPtr element = Parse(expected, &errors);
649   ASSERT_TRUE(element);
650   ASSERT_TRUE(errors.empty());
651   LineStringPtr linestring = AsLineString(element);
652   ASSERT_TRUE(linestring);
653   ASSERT_TRUE(linestring->has_id());
654   ASSERT_EQ(string("linestring-id"), linestring->get_id());
655   ASSERT_TRUE(linestring->has_extrude());
656   ASSERT_EQ(1, linestring->get_extrude());
657   ASSERT_TRUE(linestring->has_tessellate());
658   ASSERT_EQ(1, linestring->get_tessellate());
659   ASSERT_FALSE(linestring->has_altitudemode());
660   ASSERT_TRUE(linestring->has_gx_altitudemode());
661   ASSERT_EQ(GX_ALTITUDEMODE_RELATIVETOSEAFLOOR,
662             linestring->get_gx_altitudemode());
663 }
664 
665 // Test LinearRing.
666 class LinearRingTest : public testing::Test {
667  protected:
SetUp()668   virtual void SetUp() {
669     linearring_ = KmlFactory::GetFactory()->CreateLinearRing();
670   }
671 
672   LinearRingPtr linearring_;
673 };
674 
TEST_F(LinearRingTest,TestType)675 TEST_F(LinearRingTest, TestType) {
676   ASSERT_EQ(Type_LinearRing, linearring_->Type());
677   ASSERT_TRUE(linearring_->IsA(Type_LinearRing));
678   ASSERT_TRUE(linearring_->IsA(Type_Geometry));
679   ASSERT_TRUE(linearring_->IsA(Type_Object));
680 }
681 
682 // Verify proper defaults:
TEST_F(LinearRingTest,TestDefaults)683 TEST_F(LinearRingTest, TestDefaults) {
684   ASSERT_FALSE(linearring_->has_id());
685   ASSERT_FALSE(linearring_->has_targetid());
686   ASSERT_FALSE(linearring_->has_extrude());
687   ASSERT_FALSE(linearring_->get_extrude());
688   ASSERT_FALSE(linearring_->has_tessellate());
689   ASSERT_FALSE(linearring_->get_tessellate());
690   ASSERT_FALSE(linearring_->has_altitudemode());
691   ASSERT_EQ(ALTITUDEMODE_CLAMPTOGROUND, linearring_->get_altitudemode());
692   ASSERT_FALSE(linearring_->has_gx_altitudemode());
693   ASSERT_EQ(GX_ALTITUDEMODE_CLAMPTOSEAFLOOR,
694             linearring_->get_gx_altitudemode());
695   ASSERT_FALSE(linearring_->has_coordinates());
696 }
697 
698 // Verify setting default makes has_xxx() true:
TEST_F(LinearRingTest,TestSetToDefaultValues)699 TEST_F(LinearRingTest, TestSetToDefaultValues) {
700   linearring_->set_extrude(linearring_->get_extrude());
701   linearring_->set_tessellate(linearring_->get_tessellate());
702   linearring_->set_altitudemode(linearring_->get_altitudemode());
703   linearring_->set_gx_altitudemode(linearring_->get_gx_altitudemode());
704   linearring_->set_coordinates(NULL);  // should not crash
705   ASSERT_TRUE(linearring_->has_extrude());
706   ASSERT_TRUE(linearring_->has_tessellate());
707   ASSERT_TRUE(linearring_->has_altitudemode());
708   ASSERT_TRUE(linearring_->has_gx_altitudemode());
709   ASSERT_FALSE(linearring_->has_coordinates());  // ptr is null
710 }
711 
712 // Verify set, get, has, clear:
TEST_F(LinearRingTest,TestSetGetHasClear)713 TEST_F(LinearRingTest, TestSetGetHasClear) {
714   // Non-default values:
715   bool extrude = true;
716   bool tessellate = true;
717   AltitudeModeEnum altitudemode = ALTITUDEMODE_RELATIVETOGROUND;
718   GxAltitudeModeEnum gx_altitudemode = GX_ALTITUDEMODE_RELATIVETOSEAFLOOR;
719   CoordinatesPtr coordinates = KmlFactory::GetFactory()->CreateCoordinates();
720 
721   // Set all fields:
722   linearring_->set_extrude(extrude);
723   linearring_->set_tessellate(tessellate);
724   linearring_->set_altitudemode(altitudemode);
725   linearring_->set_gx_altitudemode(gx_altitudemode);
726   linearring_->set_coordinates(coordinates);
727 
728   // Verify getter and has_xxx():
729   ASSERT_TRUE(linearring_->has_extrude());
730   ASSERT_EQ(extrude, linearring_->get_extrude());
731   ASSERT_TRUE(linearring_->has_tessellate());
732   ASSERT_EQ(tessellate, linearring_->get_tessellate());
733   ASSERT_TRUE(linearring_->has_altitudemode());
734   ASSERT_EQ(altitudemode, linearring_->get_altitudemode());
735   ASSERT_TRUE(linearring_->has_gx_altitudemode());
736   ASSERT_EQ(gx_altitudemode, linearring_->get_gx_altitudemode());
737   ASSERT_TRUE(linearring_->has_coordinates());
738   ASSERT_EQ(coordinates, linearring_->get_coordinates());
739 
740   // Clear all fields:
741   linearring_->clear_extrude();
742   linearring_->clear_tessellate();
743   linearring_->clear_altitudemode();
744   linearring_->clear_gx_altitudemode();
745   linearring_->clear_coordinates();
746 }
747 
TEST_F(LinearRingTest,TestSerialize)748 TEST_F(LinearRingTest, TestSerialize) {
749   linearring_->set_id("linearring-id");
750   linearring_->set_tessellate(false);
751   linearring_->set_coordinates(KmlFactory::GetFactory()->CreateCoordinates());
752   string expected(
753     "<LinearRing id=\"linearring-id\">"
754     "<tessellate>0</tessellate>"
755     "<coordinates/>"
756     "</LinearRing>"
757   );
758   ASSERT_EQ(expected, SerializeRaw(linearring_));
759 }
760 
TEST_F(LinearRingTest,TestSerializeParseAll)761 TEST_F(LinearRingTest, TestSerializeParseAll) {
762   linearring_->set_id("linearring-id");
763   linearring_->set_extrude(false);
764   linearring_->set_tessellate(false);
765   linearring_->set_gx_altitudemode(GX_ALTITUDEMODE_CLAMPTOSEAFLOOR);
766   linearring_->set_coordinates(KmlFactory::GetFactory()->CreateCoordinates());
767   string expected(
768     "<LinearRing id=\"linearring-id\">"
769     "<extrude>0</extrude>"
770     "<tessellate>0</tessellate>"
771     "<gx:altitudeMode>clampToSeaFloor</gx:altitudeMode>"
772     "<coordinates/>"
773     "</LinearRing>"
774   );
775   ASSERT_EQ(expected, SerializeRaw(linearring_));
776   string errors;
777   ElementPtr element = Parse(expected, &errors);
778   ASSERT_TRUE(element);
779   ASSERT_TRUE(errors.empty());
780   LinearRingPtr linearring = AsLinearRing(element);
781   ASSERT_TRUE(linearring);
782   ASSERT_TRUE(linearring->has_id());
783   ASSERT_EQ(string("linearring-id"), linearring->get_id());
784   ASSERT_TRUE(linearring->has_extrude());
785   ASSERT_EQ(0, linearring->get_extrude());
786   ASSERT_TRUE(linearring->has_tessellate());
787   ASSERT_EQ(0, linearring->get_tessellate());
788   ASSERT_FALSE(linearring->has_altitudemode());
789   ASSERT_TRUE(linearring->has_gx_altitudemode());
790   ASSERT_EQ(GX_ALTITUDEMODE_CLAMPTOSEAFLOOR,
791             linearring->get_gx_altitudemode());
792 }
793 
794 // Test OuterBoundaryIs.
795 class OuterBoundaryIsTest : public testing::Test {
796  protected:
SetUp()797   virtual void SetUp() {
798     outerboundaryis_ = KmlFactory::GetFactory()->CreateOuterBoundaryIs();
799   }
800 
801   OuterBoundaryIsPtr outerboundaryis_;
802 };
803 
TEST_F(OuterBoundaryIsTest,TestType)804 TEST_F(OuterBoundaryIsTest, TestType) {
805   ASSERT_EQ(Type_outerBoundaryIs, outerboundaryis_->Type());
806   ASSERT_TRUE(outerboundaryis_->IsA(Type_outerBoundaryIs));
807 }
808 
809 // Verify proper defaults:
TEST_F(OuterBoundaryIsTest,TestDefaults)810 TEST_F(OuterBoundaryIsTest, TestDefaults) {
811   ASSERT_FALSE(outerboundaryis_->has_linearring());
812 }
813 
TEST_F(OuterBoundaryIsTest,TestSetGetHasClear)814 TEST_F(OuterBoundaryIsTest, TestSetGetHasClear) {
815   // Give it the only possible child:
816   outerboundaryis_->set_linearring(
817       KmlFactory::GetFactory()->CreateLinearRing());
818   ASSERT_TRUE(outerboundaryis_->has_linearring());
819   ASSERT_TRUE(outerboundaryis_->get_linearring());
820   // Clear it and verify we're back to the default state.
821   outerboundaryis_->clear_linearring();
822 }
823 
824 // Test InnerBoundaryIs.
825 class InnerBoundaryIsTest : public testing::Test {
826  protected:
SetUp()827   virtual void SetUp() {
828     innerboundaryis_ = KmlFactory::GetFactory()->CreateInnerBoundaryIs();
829   }
830 
831   InnerBoundaryIsPtr innerboundaryis_;
832 };
833 
TEST_F(InnerBoundaryIsTest,TestType)834 TEST_F(InnerBoundaryIsTest, TestType) {
835   ASSERT_EQ(Type_innerBoundaryIs, innerboundaryis_->Type());
836   ASSERT_TRUE(innerboundaryis_->IsA(Type_innerBoundaryIs));
837 }
838 
839 // Verify proper defaults:
TEST_F(InnerBoundaryIsTest,TestDefaults)840 TEST_F(InnerBoundaryIsTest, TestDefaults) {
841   ASSERT_FALSE(innerboundaryis_->has_linearring());
842 }
843 
TEST_F(InnerBoundaryIsTest,TestSetGetHasClear)844 TEST_F(InnerBoundaryIsTest, TestSetGetHasClear) {
845   // Give it the only possible child:
846   innerboundaryis_->set_linearring(
847       KmlFactory::GetFactory()->CreateLinearRing());
848   ASSERT_TRUE(innerboundaryis_->has_linearring());
849   ASSERT_TRUE(innerboundaryis_->get_linearring());
850   // Clear it and verify we're back to the default state.
851   innerboundaryis_->clear_linearring();
852 }
853 
854 // TestPolygon
855 class PolygonTest : public testing::Test {
856  protected:
SetUp()857   virtual void SetUp() {
858     polygon_ = KmlFactory::GetFactory()->CreatePolygon();
859   }
860 
861   PolygonPtr polygon_;
862 };
863 
864 // Verify proper Type.
TEST_F(PolygonTest,TestType)865 TEST_F(PolygonTest, TestType) {
866   ASSERT_EQ(Type_Polygon, polygon_->Type());
867   ASSERT_TRUE(polygon_->IsA(Type_Polygon));
868   ASSERT_TRUE(polygon_->IsA(Type_Geometry));
869   ASSERT_TRUE(polygon_->IsA(Type_Object));
870 }
871 
872 // Verify proper defaults.
TEST_F(PolygonTest,TestDefaults)873 TEST_F(PolygonTest, TestDefaults) {
874   ASSERT_FALSE(polygon_->has_id());
875   ASSERT_FALSE(polygon_->has_targetid());
876   ASSERT_FALSE(polygon_->has_extrude());
877   ASSERT_FALSE(polygon_->get_extrude());
878   ASSERT_FALSE(polygon_->has_tessellate());
879   ASSERT_FALSE(polygon_->get_tessellate());
880   ASSERT_FALSE(polygon_->has_altitudemode());
881   ASSERT_EQ(ALTITUDEMODE_CLAMPTOGROUND, polygon_->get_altitudemode());
882   ASSERT_FALSE(polygon_->has_gx_altitudemode());
883   ASSERT_EQ(GX_ALTITUDEMODE_CLAMPTOSEAFLOOR, polygon_->get_gx_altitudemode());
884   ASSERT_FALSE(polygon_->has_outerboundaryis());
885   ASSERT_EQ(static_cast<size_t>(0), polygon_->get_innerboundaryis_array_size());
886 }
887 
888 // Verify setting default makes has_xxx() true:
TEST_F(PolygonTest,TestSetToDefaultValues)889 TEST_F(PolygonTest, TestSetToDefaultValues) {
890   polygon_->set_extrude(polygon_->get_extrude());
891   polygon_->set_tessellate(polygon_->get_tessellate());
892   polygon_->set_altitudemode(polygon_->get_altitudemode());
893   polygon_->set_gx_altitudemode(polygon_->get_gx_altitudemode());
894   polygon_->set_outerboundaryis(NULL);
895   ASSERT_TRUE(polygon_->has_extrude());
896   ASSERT_TRUE(polygon_->has_tessellate());
897   ASSERT_TRUE(polygon_->has_altitudemode());
898   ASSERT_TRUE(polygon_->has_gx_altitudemode());
899   ASSERT_FALSE(polygon_->has_outerboundaryis());  // ptr is null
900 }
901 
902 // Verify set, get, has, clear:
TEST_F(PolygonTest,TestSetGetHasClear)903 TEST_F(PolygonTest, TestSetGetHasClear) {
904   // Non-default values:
905   bool extrude = true;
906   bool tessellate = true;
907   AltitudeModeEnum altitudemode = ALTITUDEMODE_RELATIVETOGROUND;
908   GxAltitudeModeEnum gx_altitudemode = GX_ALTITUDEMODE_RELATIVETOSEAFLOOR;
909   OuterBoundaryIsPtr outerboundaryis =
910     KmlFactory::GetFactory()->CreateOuterBoundaryIs();
911 
912   // Set all fields:
913   polygon_->set_extrude(extrude);
914   polygon_->set_tessellate(tessellate);
915   polygon_->set_altitudemode(altitudemode);
916   polygon_->set_gx_altitudemode(gx_altitudemode);
917   polygon_->set_outerboundaryis(outerboundaryis);
918 
919   // Verify getter and has_xxx():
920   ASSERT_TRUE(polygon_->has_extrude());
921   ASSERT_EQ(extrude, polygon_->get_extrude());
922   ASSERT_TRUE(polygon_->has_tessellate());
923   ASSERT_EQ(tessellate, polygon_->get_tessellate());
924   ASSERT_TRUE(polygon_->has_altitudemode());
925   ASSERT_EQ(altitudemode, polygon_->get_altitudemode());
926   ASSERT_TRUE(polygon_->has_gx_altitudemode());
927   ASSERT_EQ(gx_altitudemode, polygon_->get_gx_altitudemode());
928   ASSERT_TRUE(polygon_->has_outerboundaryis());
929   ASSERT_EQ(outerboundaryis, polygon_->get_outerboundaryis());
930 
931   // Clear all fields:
932   polygon_->clear_extrude();
933   polygon_->clear_tessellate();
934   polygon_->clear_altitudemode();
935   polygon_->clear_gx_altitudemode();
936   polygon_->clear_outerboundaryis();
937 }
938 
TEST_F(PolygonTest,TestSerialize)939 TEST_F(PolygonTest, TestSerialize) {
940   polygon_->set_id("polygon-id");
941   polygon_->set_altitudemode(ALTITUDEMODE_ABSOLUTE);
942   polygon_->set_outerboundaryis(
943       KmlFactory::GetFactory()->CreateOuterBoundaryIs());
944   string expected(
945     "<Polygon id=\"polygon-id\">"
946     "<altitudeMode>absolute</altitudeMode>"
947     "<outerBoundaryIs/>"
948     "</Polygon>"
949   );
950   ASSERT_EQ(expected, SerializeRaw(polygon_));
951 }
952 
TEST_F(PolygonTest,TestSerializeParseAll)953 TEST_F(PolygonTest, TestSerializeParseAll) {
954   polygon_->set_id("polygon-id");
955   polygon_->set_extrude(true);
956   polygon_->set_tessellate(true);
957   polygon_->set_gx_altitudemode(GX_ALTITUDEMODE_RELATIVETOSEAFLOOR);
958   polygon_->set_outerboundaryis(
959       KmlFactory::GetFactory()->CreateOuterBoundaryIs());
960   string expected(
961     "<Polygon id=\"polygon-id\">"
962     "<extrude>1</extrude>"
963     "<tessellate>1</tessellate>"
964     "<gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>"
965     "<outerBoundaryIs/>"
966     "</Polygon>"
967   );
968   ASSERT_EQ(expected, SerializeRaw(polygon_));
969   string errors;
970   ElementPtr element = Parse(expected, &errors);
971   ASSERT_TRUE(element);
972   ASSERT_TRUE(errors.empty());
973   PolygonPtr polygon = AsPolygon(element);
974   ASSERT_TRUE(polygon);
975   ASSERT_TRUE(polygon->has_id());
976   ASSERT_EQ(string("polygon-id"), polygon->get_id());
977   ASSERT_TRUE(polygon->has_extrude());
978   ASSERT_EQ(1, polygon->get_extrude());
979   ASSERT_TRUE(polygon->has_tessellate());
980   ASSERT_EQ(1, polygon->get_tessellate());
981   ASSERT_FALSE(polygon->has_altitudemode());
982   ASSERT_TRUE(polygon->has_gx_altitudemode());
983   ASSERT_EQ(GX_ALTITUDEMODE_RELATIVETOSEAFLOOR,
984             polygon->get_gx_altitudemode());
985   ASSERT_TRUE(polygon->has_outerboundaryis());
986 }
987 
988 // Test MultiGeometry.
989 class MultiGeometryTest : public testing::Test {
990  protected:
SetUp()991   virtual void SetUp() {
992     multigeometry_ = KmlFactory::GetFactory()->CreateMultiGeometry();
993   }
994 
995   MultiGeometryPtr multigeometry_;
996 };
997 
TEST_F(MultiGeometryTest,TestType)998 TEST_F(MultiGeometryTest, TestType) {
999   ASSERT_EQ(Type_MultiGeometry, multigeometry_->Type());
1000   ASSERT_TRUE(multigeometry_->IsA(Type_MultiGeometry));
1001   ASSERT_TRUE(multigeometry_->IsA(Type_Geometry));
1002   ASSERT_TRUE(multigeometry_->IsA(Type_Object));
1003 }
1004 
TEST_F(MultiGeometryTest,TestDefaults)1005 TEST_F(MultiGeometryTest, TestDefaults) {
1006   ASSERT_FALSE(multigeometry_->has_id());
1007   ASSERT_FALSE(multigeometry_->has_targetid());
1008   ASSERT_EQ(static_cast<size_t>(0), multigeometry_->get_geometry_array_size());
1009 }
1010 
TEST_F(MultiGeometryTest,TestAddGetGeometries)1011 TEST_F(MultiGeometryTest, TestAddGetGeometries) {
1012   // Create some Geometries and give them to the MultiGeometry.
1013   multigeometry_->add_geometry(KmlFactory::GetFactory()->CreatePoint());
1014   multigeometry_->add_geometry(KmlFactory::GetFactory()->CreateMultiGeometry());
1015   multigeometry_->add_geometry(KmlFactory::GetFactory()->CreatePolygon());
1016   multigeometry_->add_geometry(KmlFactory::GetFactory()->CreateModel());
1017   multigeometry_->add_geometry(KmlFactory::GetFactory()->CreateLineString());
1018   multigeometry_->add_geometry(KmlFactory::GetFactory()->CreateLinearRing());
1019 
1020   // Verify the proper size and order of the geometry array:
1021   ASSERT_EQ(static_cast<size_t>(6), multigeometry_->get_geometry_array_size());
1022   ASSERT_EQ(Type_Point, multigeometry_->get_geometry_array_at(0)->Type());
1023   ASSERT_EQ(Type_MultiGeometry,
1024             multigeometry_->get_geometry_array_at(1)->Type());
1025   ASSERT_EQ(Type_Polygon, multigeometry_->get_geometry_array_at(2)->Type());
1026   ASSERT_EQ(Type_Model, multigeometry_->get_geometry_array_at(3)->Type());
1027   ASSERT_EQ(Type_LineString, multigeometry_->get_geometry_array_at(4)->Type());
1028   ASSERT_EQ(Type_LinearRing, multigeometry_->get_geometry_array_at(5)->Type());
1029 }
1030 
TEST_F(MultiGeometryTest,TestSerialize)1031 TEST_F(MultiGeometryTest, TestSerialize) {
1032   multigeometry_->set_id("multigeometry-id");
1033   multigeometry_->add_geometry(KmlFactory::GetFactory()->CreatePoint());
1034   multigeometry_->add_geometry(KmlFactory::GetFactory()->CreateLineString());
1035   multigeometry_->add_geometry(KmlFactory::GetFactory()->CreateLinearRing());
1036   multigeometry_->add_geometry(KmlFactory::GetFactory()->CreatePolygon());
1037   multigeometry_->add_geometry(KmlFactory::GetFactory()->CreateModel());
1038   multigeometry_->add_geometry(KmlFactory::GetFactory()->CreateMultiGeometry());
1039   string expected(
1040     "<MultiGeometry id=\"multigeometry-id\">"
1041     "<Point/>"
1042     "<LineString/>"
1043     "<LinearRing/>"
1044     "<Polygon/>"
1045     "<Model/>"
1046     "<MultiGeometry/>"
1047     "</MultiGeometry>"
1048   );
1049   ASSERT_EQ(expected, SerializeRaw(multigeometry_));
1050 }
1051 
1052 // Test gx:Track.
1053 class GxTrackTest: public testing::Test {
1054  protected:
SetUp()1055   virtual void SetUp() {
1056     gx_track_= KmlFactory::GetFactory()->CreateGxTrack();
1057   }
1058 
1059   GxTrackPtr gx_track_;
1060 };
1061 
TEST_F(GxTrackTest,TestType)1062 TEST_F(GxTrackTest, TestType) {
1063   ASSERT_EQ(Type_GxTrack, gx_track_->Type());
1064   ASSERT_TRUE(gx_track_->IsA(Type_GxTrack));
1065   ASSERT_TRUE(gx_track_->IsA(Type_Geometry));
1066   ASSERT_TRUE(gx_track_->IsA(Type_Object));
1067 }
1068 
TEST_F(GxTrackTest,TestDefaults)1069 TEST_F(GxTrackTest, TestDefaults) {
1070   ASSERT_FALSE(gx_track_->has_id());
1071   ASSERT_FALSE(gx_track_->has_targetid());
1072   ASSERT_EQ(static_cast<size_t>(0), gx_track_->get_when_array_size());
1073   ASSERT_EQ(static_cast<size_t>(0), gx_track_->get_gx_coord_array_size());
1074   ASSERT_EQ(static_cast<size_t>(0), gx_track_->get_gx_angles_array_size());
1075   ASSERT_FALSE(gx_track_->has_model());
1076   ASSERT_FALSE(gx_track_->has_extendeddata());
1077 }
1078 
TEST_F(GxTrackTest,TestSetGet)1079 TEST_F(GxTrackTest, TestSetGet) {
1080   // <when> arrays
1081   const string when0("2010-02-07T19:57:44Z");
1082   const string when1("2010-02-07T19:57:45Z");
1083   gx_track_->add_when(when0);
1084   gx_track_->add_when(when1);
1085   ASSERT_EQ(static_cast<size_t>(2), gx_track_->get_when_array_size());
1086   ASSERT_EQ(when0, gx_track_->get_when_array_at(0));
1087   ASSERT_EQ(when1, gx_track_->get_when_array_at(1));
1088   // <gx:coord> arrays
1089   const Vec3 coord0(-122.0, 37.1, 100.2);
1090   const Vec3 coord1(-122.1, 37.2, 100.3);
1091   gx_track_->add_gx_coord(coord0);
1092   gx_track_->add_gx_coord(coord1);
1093   ASSERT_EQ(static_cast<size_t>(2), gx_track_->get_gx_coord_array_size());
1094   ASSERT_TRUE(coord0 == gx_track_->get_gx_coord_array_at(0));
1095   ASSERT_TRUE(coord1 == gx_track_->get_gx_coord_array_at(1));
1096   // <gx:angles> arrays
1097   const Vec3 angles0(-1.0, 7.1, 10.2);
1098   const Vec3 angles1(-1.1, 7.2, 10.3);
1099   gx_track_->add_gx_angles(angles0);
1100   gx_track_->add_gx_angles(angles1);
1101   ASSERT_EQ(static_cast<size_t>(2), gx_track_->get_gx_angles_array_size());
1102   ASSERT_TRUE(angles0 == gx_track_->get_gx_angles_array_at(0));
1103   ASSERT_TRUE(angles1 == gx_track_->get_gx_angles_array_at(1));
1104   // <Model>
1105   gx_track_->set_model(KmlFactory::GetFactory()->CreateModel());
1106   ASSERT_TRUE(gx_track_->has_model());
1107   gx_track_->clear_model();
1108   ASSERT_FALSE(gx_track_->has_model());
1109   // <ExtendedData>
1110   gx_track_->set_extendeddata(KmlFactory::GetFactory()->CreateExtendedData());
1111   ASSERT_TRUE(gx_track_->has_extendeddata());
1112   gx_track_->clear_extendeddata();
1113   ASSERT_FALSE(gx_track_->has_extendeddata());
1114 }
1115 
TEST_F(GxTrackTest,TestParse)1116 TEST_F(GxTrackTest, TestParse) {
1117   const string kGxTrackKml(
1118     "<gx:Track>"
1119     "<altitudeMode>relativeToGround</altitudeMode>"
1120     "<when>2010-02-07T19:57:44Z</when>"
1121     "<when>2010-02-07T19:57:45Z</when>"
1122     "<gx:coord>-122.1 37.2 100.3       </gx:coord>"
1123     "<gx:coord>-122.4 37.5 100.6</gx:coord>"
1124     "<gx:angles>-1.1 7.2 10.3</gx:angles>"
1125     "<gx:angles>-1.4 7.5 10.6</gx:angles>"
1126     "<Model/>"
1127     "<ExtendedData/>"
1128     "</gx:Track>"
1129   );
1130   string errors;
1131   ElementPtr element = Parse(kGxTrackKml, &errors);
1132   ASSERT_TRUE(element);
1133   ASSERT_TRUE(errors.empty());
1134   const GxTrackPtr gx_track = AsGxTrack(element);
1135   ASSERT_TRUE(gx_track);
1136   ASSERT_TRUE(gx_track->has_altitudemode());
1137   ASSERT_EQ(ALTITUDEMODE_RELATIVETOGROUND, gx_track->get_altitudemode());
1138   ASSERT_EQ(static_cast<size_t>(2), gx_track->get_when_array_size());
1139   ASSERT_EQ("2010-02-07T19:57:44Z", gx_track->get_when_array_at(0));
1140   ASSERT_EQ("2010-02-07T19:57:45Z", gx_track->get_when_array_at(1));
1141   ASSERT_EQ(static_cast<size_t>(2), gx_track->get_gx_coord_array_size());
1142   ASSERT_TRUE(Vec3(-122.1, 37.2, 100.3) == gx_track->get_gx_coord_array_at(0));
1143   ASSERT_TRUE(Vec3(-122.4, 37.5, 100.6) == gx_track->get_gx_coord_array_at(1));
1144   ASSERT_EQ(static_cast<size_t>(2), gx_track->get_gx_angles_array_size());
1145   ASSERT_TRUE(Vec3(-1.1, 7.2, 10.3) == gx_track->get_gx_angles_array_at(0));
1146   ASSERT_TRUE(Vec3(-1.4, 7.5, 10.6) == gx_track->get_gx_angles_array_at(1));
1147   ASSERT_TRUE(gx_track->has_model());
1148   ASSERT_TRUE(gx_track->has_extendeddata());
1149 }
1150 
TEST_F(GxTrackTest,TestSerialize)1151 TEST_F(GxTrackTest, TestSerialize) {
1152   gx_track_->set_altitudemode(ALTITUDEMODE_RELATIVETOGROUND);
1153   ASSERT_TRUE(gx_track_->has_altitudemode());
1154   const string when0("2010-02-07T19:57:44Z");
1155   const string when1("2010-02-07T19:57:45Z");
1156   gx_track_->add_when(when0);
1157   gx_track_->add_when(when1);
1158   const Vec3 coord0(-122.1, 37.2, 100.3);
1159   const Vec3 coord1(-122.4, 37.5, 100.6);
1160   gx_track_->add_gx_coord(coord0);
1161   gx_track_->add_gx_coord(coord1);
1162   const Vec3 angles0(-1.1, 7.2, 10.3);
1163   const Vec3 angles1(-1.4, 7.5, 10.6);
1164   gx_track_->add_gx_angles(angles0);
1165   gx_track_->add_gx_angles(angles1);
1166   gx_track_->set_model(KmlFactory::GetFactory()->CreateModel());
1167   gx_track_->set_extendeddata(KmlFactory::GetFactory()->CreateExtendedData());
1168 
1169   const string kExpected(
1170     "<gx:Track>"
1171     "<altitudeMode>relativeToGround</altitudeMode>"
1172     "<when>2010-02-07T19:57:44Z</when>"
1173     "<when>2010-02-07T19:57:45Z</when>"
1174     "<gx:coord>-122.1 37.2 100.3</gx:coord>"
1175     "<gx:coord>-122.4 37.5 100.6</gx:coord>"
1176     "<gx:angles>-1.1 7.2 10.3</gx:angles>"
1177     "<gx:angles>-1.4 7.5 10.6</gx:angles>"
1178     "<Model/>"
1179     "<ExtendedData/>"
1180     "</gx:Track>"
1181   );
1182   ASSERT_EQ(kExpected, SerializeRaw(gx_track_));
1183 }
1184 
1185 // Test gx:MultiTrack.
1186 class GxMultiTrackTest: public testing::Test {
1187  protected:
SetUp()1188   virtual void SetUp() {
1189     gx_multitrack_= KmlFactory::GetFactory()->CreateGxMultiTrack();
1190   }
1191 
1192   GxMultiTrackPtr gx_multitrack_;
1193 };
1194 
TEST_F(GxMultiTrackTest,TestType)1195 TEST_F(GxMultiTrackTest, TestType) {
1196   ASSERT_EQ(Type_GxMultiTrack, gx_multitrack_->Type());
1197   ASSERT_TRUE(gx_multitrack_->IsA(Type_GxMultiTrack));
1198   ASSERT_TRUE(gx_multitrack_->IsA(Type_Geometry));
1199   ASSERT_TRUE(gx_multitrack_->IsA(Type_Object));
1200 }
1201 
TEST_F(GxMultiTrackTest,TestDefaults)1202 TEST_F(GxMultiTrackTest, TestDefaults) {
1203   ASSERT_FALSE(gx_multitrack_->has_id());
1204   ASSERT_FALSE(gx_multitrack_->has_targetid());
1205   ASSERT_FALSE(gx_multitrack_->has_gx_interpolate());
1206   ASSERT_FALSE(gx_multitrack_->get_gx_interpolate());
1207   ASSERT_EQ(static_cast<size_t>(0), gx_multitrack_->get_gx_track_array_size());
1208 }
1209 
TEST_F(GxMultiTrackTest,TestSetGet)1210 TEST_F(GxMultiTrackTest, TestSetGet) {
1211   gx_multitrack_->set_gx_interpolate(true);
1212   ASSERT_TRUE(gx_multitrack_->has_gx_interpolate());
1213   ASSERT_TRUE(gx_multitrack_->get_gx_interpolate());
1214   gx_multitrack_->clear_gx_interpolate();
1215   ASSERT_FALSE(gx_multitrack_->has_gx_interpolate());
1216   ASSERT_FALSE(gx_multitrack_->get_gx_interpolate());
1217   gx_multitrack_->add_gx_track(KmlFactory::GetFactory()->CreateGxTrack());
1218   gx_multitrack_->add_gx_track(KmlFactory::GetFactory()->CreateGxTrack());
1219   ASSERT_EQ(static_cast<size_t>(2), gx_multitrack_->get_gx_track_array_size());
1220 }
1221 
TEST_F(GxMultiTrackTest,TestSerialize)1222 TEST_F(GxMultiTrackTest, TestSerialize) {
1223   gx_multitrack_->set_gx_interpolate(true);
1224   gx_multitrack_->add_gx_track(KmlFactory::GetFactory()->CreateGxTrack());
1225   gx_multitrack_->add_gx_track(KmlFactory::GetFactory()->CreateGxTrack());
1226   gx_multitrack_->set_id("x");
1227   const string kExpected(
1228     "<gx:MultiTrack id=\"x\">"
1229     "<gx:interpolate>1</gx:interpolate>"
1230     "<gx:Track/>"
1231     "<gx:Track/>"
1232     "</gx:MultiTrack>"
1233   );
1234   ASSERT_EQ(kExpected, SerializeRaw(gx_multitrack_));
1235 }
1236 
1237 }  // end namespace kmldom
1238