/test/plugin/file/kml/tour/tourparser.test.js

https://github.com/ngageoint/opensphere · JavaScript · 280 lines · 229 code · 34 blank · 17 comment · 0 complexity · a75b6f13ea0686672b1a61ad5b9de836 MD5 · raw file

  1. goog.require('ol.xml');
  2. goog.require('os.map.FlightMode');
  3. goog.require('plugin.file.kml.tour.FlyTo');
  4. goog.require('plugin.file.kml.tour.SoundCue');
  5. goog.require('plugin.file.kml.tour.Tour');
  6. goog.require('plugin.file.kml.tour.TourControl');
  7. goog.require('plugin.file.kml.tour.Wait');
  8. goog.require('plugin.file.kml.tour.parseTour');
  9. describe('plugin.file.kml.tour.parseTour', function() {
  10. const xml = goog.module.get('ol.xml');
  11. const {default: FlightMode} = goog.module.get('os.map.FlightMode');
  12. const {default: FlyTo} = goog.module.get('plugin.file.kml.tour.FlyTo');
  13. const {default: SoundCue} = goog.module.get('plugin.file.kml.tour.SoundCue');
  14. const {default: TourControl} = goog.module.get('plugin.file.kml.tour.TourControl');
  15. const {default: Wait} = goog.module.get('plugin.file.kml.tour.Wait');
  16. const {default: parseTour} = goog.module.get('plugin.file.kml.tour.parseTour');
  17. // match opening/closing tags for a KML tour element, with a trailing space (has attributes) or GT (no attributes)
  18. var tourElRegexp = /(<\/?)(Tour|Playlist|FlyTo|SoundCue|TourControl|Wait|delayedStart|duration|flyToMode)([ >])/g;
  19. /**
  20. * Prefix KML tour element names.
  21. * @param {string} text The KML text.
  22. * @param {string} namespace The namespace.
  23. * @return {string} The replaced text.
  24. */
  25. var replaceText = function(text, namespace) {
  26. return namespace ? text.replace(tourElRegexp, '$1' + 'gx:' + '$2>') : text;
  27. };
  28. /**
  29. * Parse KML tour text and return the root node.
  30. * @param {string} text The KML tour text.
  31. * @param {string} namespace The namespace.
  32. * @return {Element} The root Tour element.
  33. */
  34. var getTourNode = function(text, namespace) {
  35. var node = xml.parse(replaceText(text, namespace));
  36. return node.firstElementChild;
  37. };
  38. var runTests = function(namespace) {
  39. describe(namespace + 'Tour', function() {
  40. it('parses a ' + namespace + 'Tour element', function() {
  41. var text =
  42. '<Tour>' +
  43. ' <name>Test Tour</name>' +
  44. ' <description>Test Tour Description</description>' +
  45. ' <Playlist></Playlist>' +
  46. '</Tour>';
  47. var tour = parseTour(getTourNode(text));
  48. expect(tour).toBeDefined();
  49. expect(tour.name).toBe('Test Tour');
  50. expect(tour.description).toBe('Test Tour Description');
  51. expect(tour.getPlaylist().length).toBe(0);
  52. });
  53. it('parses a ' + namespace + 'FlyTo element without duration or flyToMode', function() {
  54. var text =
  55. '<Tour>' +
  56. ' <name>Test Tour</name>' +
  57. ' <description>Test Tour Description</description>' +
  58. ' <Playlist>' +
  59. ' <FlyTo></FlyTo>' +
  60. ' </Playlist>' +
  61. '</Tour>';
  62. var tour = parseTour(getTourNode(text));
  63. var flyTo = tour.getPlaylist()[0];
  64. expect(flyTo instanceof FlyTo).toBe(true);
  65. expect(flyTo.duration_).toBe(FlyTo.DEFAULT_DURATION);
  66. expect(flyTo.options_.flightMode).toBe(FlightMode.BOUNCE);
  67. });
  68. it('parses a ' + namespace + 'FlyTo element with duration', function() {
  69. var text =
  70. '<Tour>' +
  71. ' <name>Test Tour</name>' +
  72. ' <description>Test Tour Description</description>' +
  73. ' <Playlist>' +
  74. ' <FlyTo>' +
  75. ' <duration>10</duration>' +
  76. ' </FlyTo>' +
  77. ' </Playlist>' +
  78. '</Tour>';
  79. var tour = parseTour(getTourNode(text));
  80. var flyTo = tour.getPlaylist()[0];
  81. expect(flyTo instanceof FlyTo).toBe(true);
  82. expect(flyTo.duration_).toBe(10000);
  83. });
  84. it('parses a ' + namespace + 'FlyTo element with flyToMode', function() {
  85. var text =
  86. '<Tour>' +
  87. ' <name>Test Tour</name>' +
  88. ' <description>Test Tour Description</description>' +
  89. ' <Playlist>' +
  90. ' <FlyTo>' +
  91. ' <flyToMode>smooth</flyToMode>' +
  92. ' </FlyTo>' +
  93. ' </Playlist>' +
  94. '</Tour>';
  95. var tour = parseTour(getTourNode(text));
  96. var flyTo = tour.getPlaylist()[0];
  97. expect(flyTo instanceof FlyTo).toBe(true);
  98. expect(flyTo.options_.flightMode).toBe(FlightMode.SMOOTH);
  99. });
  100. it('parses a ' + namespace + 'FlyTo element with invalid flyToMode', function() {
  101. var text =
  102. '<Tour>' +
  103. ' <name>Test Tour</name>' +
  104. ' <description>Test Tour Description</description>' +
  105. ' <Playlist>' +
  106. ' <FlyTo>' +
  107. ' <flyToMode>teleport</flyToMode>' +
  108. ' </FlyTo>' +
  109. ' </Playlist>' +
  110. '</Tour>';
  111. var tour = parseTour(getTourNode(text));
  112. var flyTo = tour.getPlaylist()[0];
  113. expect(flyTo instanceof FlyTo).toBe(true);
  114. expect(flyTo.options_.flightMode).toBe(FlightMode.BOUNCE);
  115. });
  116. it('parses a ' + namespace + 'FlyTo element with a Camera definition', function() {
  117. var text =
  118. '<Tour>' +
  119. ' <name>Test Tour</name>' +
  120. ' <description>Test Tour Description</description>' +
  121. ' <Playlist>' +
  122. ' <FlyTo>' +
  123. ' <Camera>' +
  124. ' <longitude>123.45</longitude>' +
  125. ' <latitude>-67.89</latitude>' +
  126. ' <altitude>12345</altitude>' +
  127. ' <heading>-1.234</heading>' +
  128. ' <tilt>42</tilt>' +
  129. ' <altitudeMode>absolute</altitudeMode>' +
  130. ' </Camera>' +
  131. ' </FlyTo>' +
  132. ' </Playlist>' +
  133. '</Tour>';
  134. var tour = parseTour(getTourNode(text));
  135. expect(tour).toBeDefined();
  136. var playlist = tour.getPlaylist();
  137. expect(playlist.length).toBe(1);
  138. var flyTo = playlist[0];
  139. expect(flyTo instanceof FlyTo).toBe(true);
  140. expect(flyTo.options_.center[0]).toBe(123.45);
  141. expect(flyTo.options_.center[1]).toBe(-67.89);
  142. expect(flyTo.options_.altitude).toBe(12345);
  143. expect(flyTo.options_.heading).toBe(-1.234);
  144. // tilt converted to Cesium pitch
  145. expect(flyTo.options_.tilt).toBeUndefined();
  146. expect(flyTo.options_.pitch).toBe(42);
  147. });
  148. it('parses a ' + namespace + 'FlyTo element with a LookAt definition', function() {
  149. var text =
  150. '<Tour>' +
  151. ' <name>Test Tour</name>' +
  152. ' <description>Test Tour Description</description>' +
  153. ' <Playlist>' +
  154. ' <FlyTo>' +
  155. ' <duration>10</duration>' +
  156. ' <LookAt>' +
  157. ' <longitude>123.45</longitude>' +
  158. ' <latitude>-67.89</latitude>' +
  159. ' <altitude>150</altitude>' +
  160. ' <heading>-1.234</heading>' +
  161. ' <tilt>42</tilt>' +
  162. ' <range>12345</range>' +
  163. ' <altitudeMode>absolute</altitudeMode>' +
  164. ' </LookAt>' +
  165. ' </FlyTo>' +
  166. ' </Playlist>' +
  167. '</Tour>';
  168. var tour = parseTour(getTourNode(text));
  169. expect(tour).toBeDefined();
  170. var playlist = tour.getPlaylist();
  171. expect(playlist.length).toBe(1);
  172. var flyTo = playlist[0];
  173. expect(flyTo instanceof FlyTo).toBe(true);
  174. expect(flyTo.options_.center[0]).toBe(123.45);
  175. expect(flyTo.options_.center[1]).toBe(-67.89);
  176. expect(flyTo.options_.altitude).toBe(150);
  177. expect(flyTo.options_.heading).toBe(-1.234);
  178. expect(flyTo.options_.range).toBe(12345);
  179. // tilt converted to Cesium pitch
  180. expect(flyTo.options_.tilt).toBeUndefined();
  181. expect(flyTo.options_.pitch).toBe(42);
  182. });
  183. it('parses a ' + namespace + 'SoundCue element', function() {
  184. var href = 'https://test.com/test.mp3';
  185. var delayedStart = 10;
  186. var text =
  187. '<Tour>' +
  188. ' <name>Test Tour</name>' +
  189. ' <description>Test Tour Description</description>' +
  190. ' <Playlist>' +
  191. ' <SoundCue>' +
  192. ' <href>' + href + '</href>' +
  193. ' <delayedStart>' + delayedStart + '</delayedStart>' +
  194. ' </SoundCue>' +
  195. ' </Playlist>' +
  196. '</Tour>';
  197. var tour = parseTour(getTourNode(text));
  198. expect(tour).toBeDefined();
  199. var playlist = tour.getPlaylist();
  200. expect(playlist.length).toBe(1);
  201. expect(playlist[0] instanceof SoundCue).toBe(true);
  202. expect(playlist[0].href_).toBe(href);
  203. expect(playlist[0].duration_).toBe(delayedStart * 1000);
  204. });
  205. it('parses a ' + namespace + 'TourControl element', function() {
  206. var text =
  207. '<Tour>' +
  208. ' <name>Test Tour</name>' +
  209. ' <description>Test Tour Description</description>' +
  210. ' <Playlist>' +
  211. ' <TourControl></TourControl>' +
  212. ' </Playlist>' +
  213. '</Tour>';
  214. var tour = parseTour(getTourNode(text));
  215. expect(tour).toBeDefined();
  216. var playlist = tour.getPlaylist();
  217. expect(playlist.length).toBe(1);
  218. expect(playlist[0] instanceof TourControl).toBe(true);
  219. expect(playlist[0].tour_).toBe(tour);
  220. });
  221. it('parses a ' + namespace + 'Wait element', function() {
  222. var duration = 10;
  223. var text =
  224. '<Tour>' +
  225. ' <name>Test Tour</name>' +
  226. ' <description>Test Tour Description</description>' +
  227. ' <Playlist>' +
  228. ' <Wait>' +
  229. ' <duration>' + duration + '</duration>' +
  230. ' </Wait>' +
  231. ' </Playlist>' +
  232. '</Tour>';
  233. var tour = parseTour(getTourNode(text));
  234. expect(tour).toBeDefined();
  235. var playlist = tour.getPlaylist();
  236. expect(playlist.length).toBe(1);
  237. expect(playlist[0] instanceof Wait).toBe(true);
  238. expect(playlist[0].duration_).toBe(duration * 1000);
  239. });
  240. });
  241. };
  242. // KML 2.2 with gx extension
  243. runTests('gx:');
  244. // KML 2.3
  245. runTests('');
  246. });