@vitessce/config 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,9 @@
1
- import { generateConfigs } from './VitessceAutoConfig.js';
2
- describe('src/VitessceAutoConfig.js', () => {
1
+ import { describe, it, expect } from 'vitest';
2
+ import { generateConfig, getHintOptions } from './VitessceAutoConfig.js';
3
+ import { HINT_TYPE_TO_FILE_TYPE_MAP } from './constants.js';
4
+ describe('generateConfig', () => {
3
5
  it('generates config for OME-TIFF file correctly', async () => {
4
6
  const urls = ['somefile.ome.tif'];
5
- const expectedName = urls[0].split('/').at(-1);
6
7
  const expectedConfig = {
7
8
  version: '1.0.15',
8
9
  name: 'An automatically generated config. Adjust values and add layout components if needed.',
@@ -10,7 +11,7 @@ describe('src/VitessceAutoConfig.js', () => {
10
11
  datasets: [
11
12
  {
12
13
  uid: 'A',
13
- name: expectedName,
14
+ name: 'An automatically generated view config for dataset. Adjust values and add layout components if needed.',
14
15
  files: [
15
16
  {
16
17
  fileType: 'raster.json',
@@ -20,7 +21,7 @@ describe('src/VitessceAutoConfig.js', () => {
20
21
  metadata: {
21
22
  isBitmask: false,
22
23
  },
23
- name: expectedName,
24
+ name: 'somefile.ome.tif',
24
25
  type: 'ome-tiff',
25
26
  url: urls[0],
26
27
  },
@@ -75,12 +76,11 @@ describe('src/VitessceAutoConfig.js', () => {
75
76
  ],
76
77
  initStrategy: 'auto',
77
78
  };
78
- const config = await generateConfigs(urls);
79
+ const config = await generateConfig(urls);
79
80
  expect(config).toEqual(expectedConfig);
80
81
  });
81
82
  it('generates config for OME-ZARR file correctly', async () => {
82
83
  const urls = ['anotherfile.ome.zarr'];
83
- const expectedName = urls[0].split('/').at(-1);
84
84
  const expectedConfig = {
85
85
  version: '1.0.15',
86
86
  name: 'An automatically generated config. Adjust values and add layout components if needed.',
@@ -88,7 +88,7 @@ describe('src/VitessceAutoConfig.js', () => {
88
88
  datasets: [
89
89
  {
90
90
  uid: 'A',
91
- name: expectedName,
91
+ name: 'An automatically generated view config for dataset. Adjust values and add layout components if needed.',
92
92
  files: [
93
93
  {
94
94
  url: urls[0],
@@ -132,26 +132,19 @@ describe('src/VitessceAutoConfig.js', () => {
132
132
  y: 6,
133
133
  w: 6,
134
134
  h: 6,
135
- },
136
- {
137
- component: 'status',
138
- coordinationScopes: {
139
- dataset: 'A',
135
+ props: {
136
+ disable3d: [],
137
+ disableChannelsIfRgbDetected: true,
140
138
  },
141
- x: 6,
142
- y: 6,
143
- w: 6,
144
- h: 6,
145
139
  },
146
140
  ],
147
141
  initStrategy: 'auto',
148
142
  };
149
- const config = await generateConfigs(urls);
143
+ const config = await generateConfig(urls);
150
144
  expect(config).toEqual(expectedConfig);
151
145
  });
152
146
  it('generates config for Anndata-ZARR file correctly', async () => {
153
- const urls = ['http://localhost:51204/@fixtures/zarr/partials/.anndata.zarr'];
154
- const expectedName = urls[0].split('/').at(-1);
147
+ const urls = ['http://localhost:4204/@fixtures/zarr/partials/.anndata.zarr'];
155
148
  const expectedConfig = {
156
149
  version: '1.0.15',
157
150
  name: 'An automatically generated config. Adjust values and add layout components if needed.',
@@ -159,7 +152,7 @@ describe('src/VitessceAutoConfig.js', () => {
159
152
  datasets: [
160
153
  {
161
154
  uid: 'A',
162
- name: expectedName,
155
+ name: 'An automatically generated view config for dataset. Adjust values and add layout components if needed.',
163
156
  files: [
164
157
  {
165
158
  url: urls[0],
@@ -215,7 +208,7 @@ describe('src/VitessceAutoConfig.js', () => {
215
208
  x: 0,
216
209
  y: 0,
217
210
  w: 6,
218
- h: 6,
211
+ h: 4,
219
212
  },
220
213
  {
221
214
  component: 'scatterplot',
@@ -226,7 +219,27 @@ describe('src/VitessceAutoConfig.js', () => {
226
219
  x: 6,
227
220
  y: 0,
228
221
  w: 6,
229
- h: 6,
222
+ h: 4,
223
+ },
224
+ {
225
+ component: 'obsSetSizes',
226
+ coordinationScopes: {
227
+ dataset: 'A',
228
+ },
229
+ h: 4,
230
+ w: 6,
231
+ x: 0,
232
+ y: 4,
233
+ },
234
+ {
235
+ component: 'obsSetFeatureValueDistribution',
236
+ coordinationScopes: {
237
+ dataset: 'A',
238
+ },
239
+ h: 4,
240
+ w: 6,
241
+ x: 6,
242
+ y: 4,
230
243
  },
231
244
  {
232
245
  component: 'heatmap',
@@ -234,9 +247,9 @@ describe('src/VitessceAutoConfig.js', () => {
234
247
  dataset: 'A',
235
248
  },
236
249
  x: 0,
237
- y: 6,
250
+ y: 8,
238
251
  w: 6,
239
- h: 6,
252
+ h: 4,
240
253
  props: {
241
254
  transpose: true,
242
255
  },
@@ -247,19 +260,18 @@ describe('src/VitessceAutoConfig.js', () => {
247
260
  dataset: 'A',
248
261
  },
249
262
  x: 6,
250
- y: 6,
263
+ y: 8,
251
264
  w: 6,
252
- h: 6,
265
+ h: 4,
253
266
  },
254
267
  ],
255
268
  initStrategy: 'auto',
256
269
  };
257
- const config = await generateConfigs(urls);
270
+ const config = await generateConfig(urls);
258
271
  expect(config).toEqual(expectedConfig);
259
272
  });
260
- it('generates empty config for Anndata-ZARR file with empty .zmetadata', async () => {
261
- const urls = ['http://localhost:51204/@fixtures/zarr/partials/emptymeta.h5ad.zarr'];
262
- const expectedName = urls[0].split('/').at(-1);
273
+ it('generates correct config for Anndata-ZARR file with empty .zmetadata', async () => {
274
+ const urls = ['http://localhost:4204/@fixtures/zarr/partials/emptymeta.h5ad.zarr'];
263
275
  const expectedConfig = {
264
276
  version: '1.0.15',
265
277
  name: 'An automatically generated config. Adjust values and add layout components if needed.',
@@ -267,7 +279,7 @@ describe('src/VitessceAutoConfig.js', () => {
267
279
  datasets: [
268
280
  {
269
281
  uid: 'A',
270
- name: expectedName,
282
+ name: 'An automatically generated view config for dataset. Adjust values and add layout components if needed.',
271
283
  files: [
272
284
  {
273
285
  url: urls[0],
@@ -292,15 +304,41 @@ describe('src/VitessceAutoConfig.js', () => {
292
304
  A: 'A',
293
305
  },
294
306
  },
295
- layout: [],
307
+ layout: [
308
+ {
309
+ component: 'obsSetSizes',
310
+ coordinationScopes: {
311
+ dataset: 'A',
312
+ },
313
+ h: 6,
314
+ w: 12,
315
+ x: 0,
316
+ y: 0,
317
+ },
318
+ {
319
+ component: 'obsSetFeatureValueDistribution',
320
+ coordinationScopes: {
321
+ dataset: 'A',
322
+ },
323
+ h: 6,
324
+ w: 12,
325
+ x: 0,
326
+ y: 6,
327
+ },
328
+ ],
296
329
  initStrategy: 'auto',
297
330
  };
298
- const config = await generateConfigs(urls);
331
+ const config = await generateConfig(urls);
299
332
  expect(config).toEqual(expectedConfig);
300
333
  });
301
334
  it('raises an error for Anndata-ZARR file with misconfigured .zmetadata', async () => {
302
- const urls = ['http://localhost:51204/@fixtures/zarr/partials/invalidmeta.adata.zarr'];
303
- await generateConfigs(urls).catch(e => expect(e.message).toContain('Could not generate config: .zmetadata file is not valid.'));
335
+ const urls = ['http://localhost:4204/@fixtures/zarr/partials/invalidmeta.adata.zarr'];
336
+ // References:
337
+ // - https://vitest.dev/api/expect.html#tothrowerror
338
+ // - https://vitest.dev/api/expect.html#rejects
339
+ await expect(() => generateConfig(urls))
340
+ .rejects
341
+ .toThrowError('Could not generate config: .zmetadata file is not valid.');
304
342
  });
305
343
  it('generates config for multiple files correctly', async () => {
306
344
  const urls = ['somefile.ome.tif', 'anoterfile.ome.zarr'];
@@ -312,7 +350,7 @@ describe('src/VitessceAutoConfig.js', () => {
312
350
  datasets: [
313
351
  {
314
352
  uid: 'A',
315
- name: expectedNames[0],
353
+ name: 'An automatically generated view config for dataset. Adjust values and add layout components if needed.',
316
354
  files: [
317
355
  {
318
356
  fileType: 'raster.json',
@@ -331,12 +369,6 @@ describe('src/VitessceAutoConfig.js', () => {
331
369
  usePhysicalSizeScaling: false,
332
370
  },
333
371
  },
334
- ],
335
- },
336
- {
337
- uid: 'B',
338
- name: expectedNames[1],
339
- files: [
340
372
  {
341
373
  url: urls[1],
342
374
  fileType: 'raster.ome-zarr',
@@ -347,7 +379,6 @@ describe('src/VitessceAutoConfig.js', () => {
347
379
  coordinationSpace: {
348
380
  dataset: {
349
381
  A: 'A',
350
- B: 'B',
351
382
  },
352
383
  },
353
384
  layout: [
@@ -358,7 +389,7 @@ describe('src/VitessceAutoConfig.js', () => {
358
389
  },
359
390
  x: 0,
360
391
  y: 0,
361
- w: 4,
392
+ w: 6,
362
393
  h: 4,
363
394
  },
364
395
  {
@@ -366,9 +397,9 @@ describe('src/VitessceAutoConfig.js', () => {
366
397
  coordinationScopes: {
367
398
  dataset: 'A',
368
399
  },
369
- x: 4,
400
+ x: 6,
370
401
  y: 0,
371
- w: 4,
402
+ w: 6,
372
403
  h: 4,
373
404
  },
374
405
  {
@@ -376,9 +407,9 @@ describe('src/VitessceAutoConfig.js', () => {
376
407
  coordinationScopes: {
377
408
  dataset: 'A',
378
409
  },
379
- x: 8,
380
- y: 0,
381
- w: 4,
410
+ x: 0,
411
+ y: 4,
412
+ w: 6,
382
413
  h: 4,
383
414
  props: {
384
415
  disable3d: [],
@@ -388,55 +419,552 @@ describe('src/VitessceAutoConfig.js', () => {
388
419
  {
389
420
  component: 'description',
390
421
  coordinationScopes: {
391
- dataset: 'B',
422
+ dataset: 'A',
392
423
  },
393
- x: 0,
424
+ x: 6,
394
425
  y: 4,
395
- w: 4,
426
+ w: 6,
396
427
  h: 4,
397
428
  },
398
429
  {
399
430
  component: 'spatial',
400
431
  coordinationScopes: {
401
- dataset: 'B',
432
+ dataset: 'A',
402
433
  },
403
- x: 4,
404
- y: 4,
405
- w: 4,
434
+ x: 0,
435
+ y: 8,
436
+ w: 6,
406
437
  h: 4,
407
438
  },
408
439
  {
409
440
  component: 'layerController',
410
441
  coordinationScopes: {
411
- dataset: 'B',
442
+ dataset: 'A',
412
443
  },
413
- x: 8,
444
+ props: {
445
+ disable3d: [],
446
+ disableChannelsIfRgbDetected: true,
447
+ },
448
+ x: 6,
449
+ y: 8,
450
+ w: 6,
451
+ h: 4,
452
+ },
453
+ ],
454
+ initStrategy: 'auto',
455
+ };
456
+ const config = await generateConfig(urls);
457
+ expect(config).toEqual(expectedConfig);
458
+ });
459
+ it('Does the parsing when .zmetadata file not present in folder', async () => {
460
+ const urls = ['http://localhost:4204/@fixtures/zarr/anndata-0.8/anndata-csr.adata.zarr'];
461
+ const expectedConfig = {
462
+ version: '1.0.15',
463
+ name: 'An automatically generated config. Adjust values and add layout components if needed.',
464
+ description: 'Populate with text relevant to this visualisation.',
465
+ datasets: [
466
+ {
467
+ uid: 'A',
468
+ name: 'An automatically generated view config for dataset. Adjust values and add layout components if needed.',
469
+ files: [
470
+ {
471
+ url: urls[0],
472
+ fileType: 'anndata.zarr',
473
+ coordinationValues: {
474
+ obsType: 'cell',
475
+ featureType: 'gene',
476
+ featureValueType: 'expression',
477
+ },
478
+ options: {
479
+ obsEmbedding: [
480
+ {
481
+ path: 'obsm/X_umap',
482
+ embeddingType: 'UMAP',
483
+ },
484
+ ],
485
+ obsFeatureMatrix: {
486
+ path: 'X',
487
+ },
488
+ obsSets: [
489
+ {
490
+ name: 'Cell Type',
491
+ path: 'obs/leiden',
492
+ },
493
+ ],
494
+ },
495
+ },
496
+ ],
497
+ },
498
+ ],
499
+ coordinationSpace: {
500
+ dataset: {
501
+ A: 'A',
502
+ },
503
+ embeddingType: {
504
+ A: 'UMAP',
505
+ },
506
+ },
507
+ layout: [
508
+ {
509
+ component: 'scatterplot',
510
+ coordinationScopes: {
511
+ dataset: 'A',
512
+ embeddingType: 'A',
513
+ },
514
+ x: 0,
515
+ y: 0,
516
+ w: 6,
517
+ h: 4,
518
+ },
519
+ {
520
+ component: 'obsSetSizes',
521
+ coordinationScopes: {
522
+ dataset: 'A',
523
+ },
524
+ h: 4,
525
+ w: 6,
526
+ x: 6,
527
+ y: 0,
528
+ },
529
+ {
530
+ component: 'obsSetFeatureValueDistribution',
531
+ coordinationScopes: {
532
+ dataset: 'A',
533
+ },
534
+ h: 4,
535
+ w: 6,
536
+ x: 0,
414
537
  y: 4,
415
- w: 4,
538
+ },
539
+ {
540
+ component: 'heatmap',
541
+ coordinationScopes: {
542
+ dataset: 'A',
543
+ },
416
544
  h: 4,
545
+ props: {
546
+ transpose: true,
547
+ },
548
+ w: 6,
549
+ x: 6,
550
+ y: 4,
417
551
  },
418
552
  {
419
- component: 'status',
553
+ component: 'featureList',
420
554
  coordinationScopes: {
421
- dataset: 'B',
555
+ dataset: 'A',
422
556
  },
557
+ h: 4,
558
+ w: 6,
423
559
  x: 0,
424
560
  y: 8,
425
- w: 4,
426
- h: 4,
427
561
  },
428
562
  ],
429
563
  initStrategy: 'auto',
430
564
  };
431
- const config = await generateConfigs(urls);
565
+ const config = await generateConfig(urls);
432
566
  expect(config).toEqual(expectedConfig);
433
567
  });
434
- it('raises an Error when .zmetadata file not present in folder', async () => {
435
- const urls = ['http://localhost:51204/@fixtures/zarr/partials/invalid.adata.zarr'];
436
- await generateConfigs(urls).catch(e => expect(e.message).toContain('Could not generate config. File .zmetadata not found in supplied file URL'));
437
- });
438
568
  it('raises an error when URL with unsupported file format is passed', async () => {
439
- const urls = ['http://localhost:51204/@fixtures/zarr/anndata-0.7/somefile.zarr'];
440
- await generateConfigs(urls).catch(e => expect(e.message).toContain('This file type is not supported.'));
569
+ const urls = ['http://localhost:4204/@fixtures/zarr/anndata-0.7/somefile.zarr'];
570
+ await generateConfig(urls, 'Transcriptomics / scRNA-seq (with heatmap)').catch(e => expect(e.message).toContain('One or more of the URLs provided point to unsupported file types.'));
571
+ });
572
+ // ********** TESTS WITH HINTS **********
573
+ it('generates config with hints for OME-TIFF dataset types correctly', async () => {
574
+ const urls = ['somefile.ome.tif'];
575
+ const expectedConfig = {
576
+ version: '1.0.15',
577
+ name: 'An automatically generated config. Adjust values and add layout components if needed.',
578
+ description: 'Populate with text relevant to this visualisation.',
579
+ datasets: [
580
+ {
581
+ uid: 'A',
582
+ name: 'An automatically generated view config for dataset. Adjust values and add layout components if needed.',
583
+ files: [
584
+ {
585
+ fileType: 'raster.json',
586
+ options: {
587
+ images: [
588
+ {
589
+ metadata: {
590
+ isBitmask: false,
591
+ },
592
+ name: 'somefile.ome.tif',
593
+ type: 'ome-tiff',
594
+ url: urls[0],
595
+ },
596
+ ],
597
+ schemaVersion: '0.0.2',
598
+ usePhysicalSizeScaling: false,
599
+ },
600
+ },
601
+ ],
602
+ },
603
+ ],
604
+ coordinationSpace: {
605
+ dataset: {
606
+ A: 'A',
607
+ },
608
+ },
609
+ layout: [
610
+ {
611
+ component: 'spatial',
612
+ coordinationScopes: {
613
+ dataset: 'A',
614
+ },
615
+ x: 0,
616
+ y: 0,
617
+ w: 8,
618
+ h: 12,
619
+ },
620
+ {
621
+ component: 'layerController',
622
+ coordinationScopes: {
623
+ dataset: 'A',
624
+ },
625
+ x: 8,
626
+ y: 0,
627
+ w: 4,
628
+ h: 7,
629
+ props: {
630
+ disable3d: [],
631
+ disableChannelsIfRgbDetected: true,
632
+ },
633
+ },
634
+ {
635
+ component: 'description',
636
+ coordinationScopes: {
637
+ dataset: 'A',
638
+ },
639
+ h: 5,
640
+ w: 4,
641
+ x: 8,
642
+ y: 9,
643
+ },
644
+ ],
645
+ initStrategy: 'auto',
646
+ };
647
+ const viewConfig = await generateConfig(urls, 'Image');
648
+ expect(viewConfig).toEqual(expectedConfig);
649
+ });
650
+ it('generates config with hints for OME-ZARR dataset types correctly', async () => {
651
+ const urls = ['somefile.ome.zarr'];
652
+ const expectedConfig = {
653
+ version: '1.0.15',
654
+ name: 'An automatically generated config. Adjust values and add layout components if needed.',
655
+ description: 'Populate with text relevant to this visualisation.',
656
+ datasets: [
657
+ {
658
+ uid: 'A',
659
+ name: 'An automatically generated view config for dataset. Adjust values and add layout components if needed.',
660
+ files: [
661
+ {
662
+ fileType: 'raster.ome-zarr',
663
+ url: 'somefile.ome.zarr',
664
+ },
665
+ ],
666
+ },
667
+ ],
668
+ coordinationSpace: {
669
+ dataset: {
670
+ A: 'A',
671
+ },
672
+ },
673
+ layout: [
674
+ {
675
+ component: 'spatial',
676
+ coordinationScopes: {
677
+ dataset: 'A',
678
+ },
679
+ x: 0,
680
+ y: 0,
681
+ w: 8,
682
+ h: 12,
683
+ },
684
+ {
685
+ component: 'layerController',
686
+ coordinationScopes: {
687
+ dataset: 'A',
688
+ },
689
+ x: 8,
690
+ y: 0,
691
+ w: 4,
692
+ h: 7,
693
+ props: {
694
+ disable3d: [],
695
+ disableChannelsIfRgbDetected: true,
696
+ },
697
+ },
698
+ {
699
+ component: 'description',
700
+ coordinationScopes: {
701
+ dataset: 'A',
702
+ },
703
+ h: 5,
704
+ w: 4,
705
+ x: 8,
706
+ y: 9,
707
+ },
708
+ ],
709
+ initStrategy: 'auto',
710
+ };
711
+ const viewConfig = await generateConfig(urls, 'Image');
712
+ expect(viewConfig).toEqual(expectedConfig);
713
+ });
714
+ it('generates config hints for Anndata-Zarr, OME-TIFF dataset types correctly', async () => {
715
+ const urls = ['somefile.ome.tif', 'http://localhost:4204/@fixtures/zarr/partials/.anndata.zarr'];
716
+ const expectedNames = [urls[0].split('/').at(-1), urls[1].split('/').at(-1)];
717
+ const expectedConfig = {
718
+ version: '1.0.15',
719
+ name: 'An automatically generated config. Adjust values and add layout components if needed.',
720
+ description: 'Populate with text relevant to this visualisation.',
721
+ datasets: [
722
+ {
723
+ uid: 'A',
724
+ name: 'An automatically generated view config for dataset. Adjust values and add layout components if needed.',
725
+ files: [
726
+ {
727
+ fileType: 'raster.json',
728
+ options: {
729
+ images: [
730
+ {
731
+ metadata: {
732
+ isBitmask: false,
733
+ },
734
+ name: expectedNames[0],
735
+ type: 'ome-tiff',
736
+ url: urls[0],
737
+ },
738
+ ],
739
+ schemaVersion: '0.0.2',
740
+ usePhysicalSizeScaling: false,
741
+ },
742
+ },
743
+ {
744
+ url: urls[1],
745
+ coordinationValues: {
746
+ featureType: 'gene',
747
+ featureValueType: 'expression',
748
+ obsType: 'cell',
749
+ },
750
+ fileType: 'anndata.zarr',
751
+ options: {
752
+ obsFeatureMatrix: {
753
+ path: 'X',
754
+ },
755
+ obsEmbedding: [
756
+ {
757
+ embeddingType: 'UMAP',
758
+ path: 'obsm/X_umap',
759
+ },
760
+ ],
761
+ obsSets: [
762
+ {
763
+ name: 'Cell Type',
764
+ path: [
765
+ 'obs/cell_type',
766
+ 'obs/disease',
767
+ 'obs/leiden',
768
+ 'obs/organism',
769
+ 'obs/self_reported_ethnicity',
770
+ 'obs/sex',
771
+ 'obs/tissue',
772
+ ],
773
+ },
774
+ ],
775
+ },
776
+ },
777
+ ],
778
+ },
779
+ ],
780
+ coordinationSpace: {
781
+ dataset: {
782
+ A: 'A',
783
+ },
784
+ spatialSegmentationLayer: {
785
+ A: {
786
+ radius: 65,
787
+ stroked: true,
788
+ visible: true,
789
+ opacity: 1,
790
+ },
791
+ },
792
+ spatialImageLayer: {
793
+ A: [
794
+ {
795
+ type: 'raster',
796
+ index: 0,
797
+ colormap: null,
798
+ transparentColor: null,
799
+ opacity: 1,
800
+ domainType: 'Min/Max',
801
+ channels: [
802
+ {
803
+ selection: {
804
+ c: 0,
805
+ },
806
+ color: [
807
+ 255,
808
+ 0,
809
+ 0,
810
+ ],
811
+ visible: true,
812
+ slider: [
813
+ 0,
814
+ 255,
815
+ ],
816
+ },
817
+ {
818
+ selection: {
819
+ c: 1,
820
+ },
821
+ color: [
822
+ 0,
823
+ 255,
824
+ 0,
825
+ ],
826
+ visible: true,
827
+ slider: [
828
+ 0,
829
+ 255,
830
+ ],
831
+ },
832
+ {
833
+ selection: {
834
+ c: 2,
835
+ },
836
+ color: [
837
+ 0,
838
+ 0,
839
+ 255,
840
+ ],
841
+ visible: true,
842
+ slider: [
843
+ 0,
844
+ 255,
845
+ ],
846
+ },
847
+ ],
848
+ },
849
+ ],
850
+ },
851
+ spatialZoom: {
852
+ A: null,
853
+ },
854
+ spatialTargetX: {
855
+ A: null,
856
+ },
857
+ spatialTargetY: {
858
+ A: null,
859
+ },
860
+ },
861
+ layout: [
862
+ {
863
+ component: 'spatial',
864
+ coordinationScopes: {
865
+ dataset: 'A',
866
+ spatialImageLayer: 'A',
867
+ spatialSegmentationLayer: 'A',
868
+ spatialTargetX: 'A',
869
+ spatialTargetY: 'A',
870
+ spatialZoom: 'A',
871
+ },
872
+ h: 6,
873
+ w: 6,
874
+ x: 0,
875
+ y: 0,
876
+ },
877
+ {
878
+ component: 'layerController',
879
+ coordinationScopes: {
880
+ dataset: 'A',
881
+ spatialImageLayer: 'A',
882
+ spatialSegmentationLayer: 'A',
883
+ spatialTargetX: 'A',
884
+ spatialTargetY: 'A',
885
+ spatialZoom: 'A',
886
+ },
887
+ h: 6,
888
+ props: {
889
+ disable3d: [],
890
+ disableChannelsIfRgbDetected: true,
891
+ },
892
+ w: 4,
893
+ x: 8,
894
+ y: 6,
895
+ },
896
+ {
897
+ component: 'heatmap',
898
+ coordinationScopes: {
899
+ dataset: 'A',
900
+ },
901
+ x: 0,
902
+ y: 6,
903
+ w: 8,
904
+ h: 6,
905
+ props: {
906
+ transpose: true,
907
+ },
908
+ },
909
+ {
910
+ component: 'obsSets',
911
+ coordinationScopes: {
912
+ dataset: 'A',
913
+ },
914
+ x: 9,
915
+ y: 0,
916
+ w: 3,
917
+ h: 6,
918
+ },
919
+ {
920
+ component: 'featureList',
921
+ coordinationScopes: {
922
+ dataset: 'A',
923
+ },
924
+ h: 6,
925
+ w: 3,
926
+ x: 6,
927
+ y: 0,
928
+ },
929
+ ],
930
+ initStrategy: 'auto',
931
+ };
932
+ const viewConfig = await generateConfig(urls, 'Spatial transcriptomics (with histology image and polygon cell segmentations)');
933
+ expect(viewConfig).toEqual(expectedConfig);
934
+ });
935
+ it('raises an error if the supplied dataset URLs and hint do not have any compatible views', async () => {
936
+ const urls = ['http://localhost:4204/@fixtures/zarr/partials/.anndata.zarr'];
937
+ const hint = 'Image';
938
+ await generateConfig(urls, hint).catch(e => expect(e.message).toContain('No views found that are compatible with the supplied dataset URLs and hint.'));
939
+ });
940
+ it('raises an error if no views are found for the supplied hint string', async () => {
941
+ const urls = ['http://localhost:4204/@fixtures/zarr/partials/.anndata.zarr'];
942
+ const hint = 'I do not exist';
943
+ await generateConfig(urls, hint).catch(e => expect(e.message).toContain('Hints config not found for the supplied hint: I do not exist'));
944
+ });
945
+ // ********** TESTS OF GET HINTS OPTIONS **********
946
+ it('returns a list of hints options for the supplied dataset URLs', async () => {
947
+ const urls = ['http://localhost:4204/@fixtures/zarr/partials/.anndata.zarr'];
948
+ const actualHintOptions = getHintOptions(urls);
949
+ expect(actualHintOptions).toEqual(HINT_TYPE_TO_FILE_TYPE_MAP['AnnData-Zarr']);
950
+ });
951
+ it('returns a list of hints options for the supplied dataset URLs', async () => {
952
+ const urls = [
953
+ 'http://localhost:4204/@fixtures/zarr/partials/.anndata.zarr',
954
+ 'somefile.ome.zarr',
955
+ 'http://localhost:4204/@fixtures/zarr/partials/.adata.zarr',
956
+ 'somefile.ome.tiff',
957
+ ];
958
+ const actualHintOptions = getHintOptions(urls);
959
+ expect(actualHintOptions).toEqual(HINT_TYPE_TO_FILE_TYPE_MAP['AnnData-Zarr,OME-TIFF']);
960
+ });
961
+ it('raises an error if no hints options are found for the supplied dataset URLs', async () => {
962
+ const urls = ['unsupportedfiletype.txt', 'unsupportedfiletype2.ome.tiff'];
963
+ try {
964
+ getHintOptions(urls);
965
+ }
966
+ catch (e) {
967
+ expect(e.message).toContain('One or more of the URLs provided point to unsupported file types.');
968
+ }
441
969
  });
442
970
  });