@@ -299,8 +299,289 @@ describe('Resource Parsers', () => {
299299 expect ( ( ) => parser . parse ( sensorml , { contentType : 'application/sml+json' } ) ) . toThrow ( 'Datastreams not defined in SensorML format' ) ;
300300 } ) ;
301301
302- it ( 'should throw on SWE format (not supported)' , ( ) => {
303- expect ( ( ) => parser . parse ( { } , { contentType : 'application/swe+json' } ) ) . toThrow ( 'SWE format not applicable' ) ;
302+ describe ( 'parseSWE' , ( ) => {
303+ it ( 'should parse SWE DataStream with DataRecord elementType' , ( ) => {
304+ const sweDataStream = {
305+ type : 'DataStream' ,
306+ id : 'ds-001' ,
307+ definition : 'http://example.org/datastreams/temp-humidity' ,
308+ label : 'Temperature and Humidity' ,
309+ description : 'Continuous temperature and humidity measurements' ,
310+ elementType : {
311+ component : {
312+ type : 'DataRecord' ,
313+ definition : 'http://example.org/observation-schema' ,
314+ label : 'Observation' ,
315+ fields : [
316+ {
317+ name : 'timestamp' ,
318+ component : {
319+ type : 'Time' ,
320+ definition : 'http://www.opengis.net/def/property/OGC/0/SamplingTime' ,
321+ label : 'Sampling Time' ,
322+ uom : {
323+ code : 'http://www.opengis.net/def/uom/ISO-8601/0/Gregorian'
324+ }
325+ }
326+ } ,
327+ {
328+ name : 'temperature' ,
329+ component : {
330+ type : 'Quantity' ,
331+ definition : 'http://example.org/def/temperature' ,
332+ label : 'Temperature' ,
333+ uom : { code : 'Cel' }
334+ }
335+ }
336+ ]
337+ }
338+ } ,
339+ encoding : {
340+ type : 'JSONEncoding'
341+ }
342+ } ;
343+
344+ const result = parser . parse ( sweDataStream , { contentType : 'application/swe+json' } ) ;
345+
346+ expect ( result . data . type ) . toBe ( 'Feature' ) ;
347+ expect ( result . data . geometry ) . toBeNull ( ) ;
348+ expect ( result . data . properties . featureType ) . toBe ( 'Datastream' ) ;
349+ expect ( result . data . properties . name ) . toBe ( 'Temperature and Humidity' ) ;
350+ expect ( result . data . properties . schema ) . toBeDefined ( ) ;
351+ expect ( result . data . properties . schema . type ) . toBe ( 'DataStream' ) ;
352+ expect ( result . data . properties . schema . elementType . type ) . toBe ( 'DataRecord' ) ;
353+ expect ( result . data . properties . schema . elementType . fields ) . toHaveLength ( 2 ) ;
354+ expect ( result . data . properties . schema . elementType . fields [ 0 ] . name ) . toBe ( 'timestamp' ) ;
355+ expect ( result . data . properties . schema . elementType . fields [ 0 ] . type ) . toBe ( 'Time' ) ;
356+ expect ( result . data . properties . schema . elementType . fields [ 1 ] . name ) . toBe ( 'temperature' ) ;
357+ expect ( result . data . properties . schema . elementType . fields [ 1 ] . type ) . toBe ( 'Quantity' ) ;
358+ expect ( result . data . properties . encoding ) . toEqual ( { type : 'JSONEncoding' } ) ;
359+ expect ( result . format . format ) . toBe ( 'swe' ) ;
360+ } ) ;
361+
362+ it ( 'should parse SWE DataRecord schema directly' , ( ) => {
363+ const sweDataRecord = {
364+ type : 'DataRecord' ,
365+ id : 'schema-001' ,
366+ definition : 'http://example.org/observation-schema' ,
367+ label : 'Observation Schema' ,
368+ fields : [
369+ {
370+ name : 'value' ,
371+ component : {
372+ type : 'Quantity' ,
373+ definition : 'http://example.org/def/measurement' ,
374+ label : 'Measurement' ,
375+ uom : { code : 'm' }
376+ }
377+ }
378+ ]
379+ } ;
380+
381+ const result = parser . parse ( sweDataRecord , { contentType : 'application/swe+json' } ) ;
382+
383+ expect ( result . data . type ) . toBe ( 'Feature' ) ;
384+ expect ( result . data . properties . schema . type ) . toBe ( 'DataRecord' ) ;
385+ expect ( result . data . properties . schema . fields ) . toHaveLength ( 1 ) ;
386+ expect ( result . data . properties . schema . fields [ 0 ] . name ) . toBe ( 'value' ) ;
387+ expect ( result . data . properties . schema . fields [ 0 ] . type ) . toBe ( 'Quantity' ) ;
388+ expect ( result . data . properties . schema . fields [ 0 ] . uom ) . toEqual ( { code : 'm' } ) ;
389+ } ) ;
390+
391+ it ( 'should handle nested DataRecord in DataStream' , ( ) => {
392+ const nestedSchema = {
393+ type : 'DataStream' ,
394+ definition : 'http://example.org/complex-stream' ,
395+ label : 'Complex Stream' ,
396+ elementType : {
397+ component : {
398+ type : 'DataRecord' ,
399+ definition : 'http://example.org/complex-record' ,
400+ label : 'Complex Record' ,
401+ fields : [
402+ {
403+ name : 'metadata' ,
404+ component : {
405+ type : 'DataRecord' ,
406+ definition : 'http://example.org/metadata' ,
407+ label : 'Metadata' ,
408+ fields : [
409+ {
410+ name : 'quality' ,
411+ component : {
412+ type : 'Text' ,
413+ definition : 'http://example.org/quality' ,
414+ label : 'Quality Flag'
415+ }
416+ }
417+ ]
418+ }
419+ }
420+ ]
421+ }
422+ }
423+ } ;
424+
425+ const result = parser . parse ( nestedSchema , { contentType : 'application/swe+json' } ) ;
426+
427+ expect ( result . data . properties . schema . elementType . fields [ 0 ] . name ) . toBe ( 'metadata' ) ;
428+ expect ( result . data . properties . schema . elementType . fields [ 0 ] . type ) . toBe ( 'DataRecord' ) ;
429+ } ) ;
430+
431+ it ( 'should handle DataArray elementType' , ( ) => {
432+ const dataArraySchema = {
433+ type : 'DataStream' ,
434+ definition : 'http://example.org/trajectory' ,
435+ label : 'Trajectory' ,
436+ elementType : {
437+ component : {
438+ type : 'DataArray' ,
439+ definition : 'http://example.org/positions' ,
440+ label : 'Positions' ,
441+ elementCount : 100 ,
442+ elementType : {
443+ component : {
444+ type : 'Vector' ,
445+ definition : 'http://example.org/position' ,
446+ label : 'Position' ,
447+ referenceFrame : 'http://www.opengis.net/def/crs/EPSG/0/4979' ,
448+ coordinates : [
449+ {
450+ name : 'lat' ,
451+ component : {
452+ type : 'Quantity' ,
453+ definition : 'http://example.org/latitude' ,
454+ label : 'Latitude' ,
455+ uom : { code : 'deg' }
456+ }
457+ }
458+ ]
459+ }
460+ }
461+ }
462+ }
463+ } ;
464+
465+ const result = parser . parse ( dataArraySchema , { contentType : 'application/swe+json' } ) ;
466+
467+ expect ( result . data . properties . schema . elementType . type ) . toBe ( 'DataArray' ) ;
468+ expect ( result . data . properties . schema . elementType . elementCount ) . toBe ( 100 ) ;
469+ expect ( result . data . properties . schema . elementType . elementType . type ) . toBe ( 'Vector' ) ;
470+ } ) ;
471+
472+ it ( 'should preserve constraints in schema' , ( ) => {
473+ const constrainedSchema = {
474+ type : 'DataRecord' ,
475+ definition : 'http://example.org/constrained' ,
476+ label : 'Constrained Schema' ,
477+ fields : [
478+ {
479+ name : 'temperature' ,
480+ component : {
481+ type : 'Quantity' ,
482+ definition : 'http://example.org/temperature' ,
483+ label : 'Temperature' ,
484+ uom : { code : 'Cel' } ,
485+ constraint : {
486+ intervals : [ [ - 40 , 60 ] ] ,
487+ significantFigures : 2
488+ }
489+ }
490+ }
491+ ]
492+ } ;
493+
494+ const result = parser . parse ( constrainedSchema , { contentType : 'application/swe+json' } ) ;
495+
496+ expect ( result . data . properties . schema . fields [ 0 ] . constraint ) . toEqual ( {
497+ intervals : [ [ - 40 , 60 ] ] ,
498+ significantFigures : 2
499+ } ) ;
500+ } ) ;
501+
502+ it ( 'should handle parsing errors gracefully' , ( ) => {
503+ const invalidSWE = {
504+ type : 'InvalidType' ,
505+ // Missing required properties
506+ } ;
507+
508+ expect ( ( ) => {
509+ parser . parse ( invalidSWE , { contentType : 'application/swe+json' } ) ;
510+ } ) . toThrow ( ) ;
511+ } ) ;
512+
513+ it ( 'should include encoding information' , ( ) => {
514+ const streamWithEncoding = {
515+ type : 'DataStream' ,
516+ definition : 'http://example.org/stream' ,
517+ label : 'Stream' ,
518+ elementType : {
519+ component : {
520+ type : 'Quantity' ,
521+ definition : 'http://example.org/value' ,
522+ label : 'Value' ,
523+ uom : { code : 'm' }
524+ }
525+ } ,
526+ encoding : {
527+ type : 'TextEncoding' ,
528+ tokenSeparator : ',' ,
529+ blockSeparator : '\n'
530+ }
531+ } ;
532+
533+ const result = parser . parse ( streamWithEncoding , { contentType : 'application/swe+json' } ) ;
534+
535+ expect ( result . data . properties . encoding ) . toEqual ( {
536+ type : 'TextEncoding' ,
537+ tokenSeparator : ',' ,
538+ blockSeparator : '\n'
539+ } ) ;
540+ } ) ;
541+
542+ it ( 'should handle Vector component extraction' , ( ) => {
543+ const vectorSchema = {
544+ type : 'DataStream' ,
545+ definition : 'http://example.org/location-stream' ,
546+ label : 'Location Stream' ,
547+ elementType : {
548+ component : {
549+ type : 'Vector' ,
550+ definition : 'http://example.org/location' ,
551+ label : 'Location' ,
552+ referenceFrame : 'http://www.opengis.net/def/crs/EPSG/0/4326' ,
553+ coordinates : [
554+ {
555+ name : 'lon' ,
556+ component : {
557+ type : 'Quantity' ,
558+ definition : 'http://example.org/longitude' ,
559+ label : 'Longitude' ,
560+ uom : { code : 'deg' }
561+ }
562+ } ,
563+ {
564+ name : 'lat' ,
565+ component : {
566+ type : 'Quantity' ,
567+ definition : 'http://example.org/latitude' ,
568+ label : 'Latitude' ,
569+ uom : { code : 'deg' }
570+ }
571+ }
572+ ]
573+ }
574+ }
575+ } ;
576+
577+ const result = parser . parse ( vectorSchema , { contentType : 'application/swe+json' } ) ;
578+
579+ expect ( result . data . properties . schema . elementType . type ) . toBe ( 'Vector' ) ;
580+ expect ( result . data . properties . schema . elementType . referenceFrame ) . toBe ( 'http://www.opengis.net/def/crs/EPSG/0/4326' ) ;
581+ expect ( result . data . properties . schema . elementType . coordinates ) . toHaveLength ( 2 ) ;
582+ expect ( result . data . properties . schema . elementType . coordinates [ 0 ] . name ) . toBe ( 'lon' ) ;
583+ expect ( result . data . properties . schema . elementType . coordinates [ 1 ] . name ) . toBe ( 'lat' ) ;
584+ } ) ;
304585 } ) ;
305586 } ) ;
306587
0 commit comments