@vitessce/vit-s 3.2.1 → 3.2.2

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.
package/dist/index.js CHANGED
@@ -35383,10 +35383,10 @@ const AUTO_INDEPENDENT_COORDINATION_TYPES = [
35383
35383
  CoordinationType$1.EMBEDDING_OBS_OPACITY
35384
35384
  ];
35385
35385
  const note = "This file is autogenerated by .changeset/post-changelog.mjs.";
35386
- const version = "3.2.1";
35387
- const date = "2023-09-13";
35386
+ const version = "3.2.2";
35387
+ const date = "2023-09-20";
35388
35388
  const branch = "changeset-release/main";
35389
- const hash = "a118dd03";
35389
+ const hash = "715881ca";
35390
35390
  const META_VERSION = {
35391
35391
  note,
35392
35392
  version,
@@ -35632,7 +35632,13 @@ function buildConfigSchema(pluginFileTypes, pluginJointFileTypes, pluginCoordina
35632
35632
  // Wrap each value schema in z.record()
35633
35633
  fromEntries(pluginCoordinationTypes.map((ct) => [
35634
35634
  ct.name,
35635
- z.record(coordinationScopeName, ct.valueSchema.optional()).optional()
35635
+ z.record(
35636
+ // For now, assume the key type is string (though it would be
35637
+ // slightly nicer if we could use the coordinationScopeName schema here).
35638
+ // Once https://github.com/colinhacks/zod/issues/2746 gets resolved
35639
+ // then we can try that approach again, but it should not be a big deal.
35640
+ ct.valueSchema.optional()
35641
+ ).optional()
35636
35642
  ]))
35637
35643
  ).strict().describe("The coordination space stores the values for each scope of each coordination object.").optional(),
35638
35644
  layout: z.array(z.object({
@@ -43699,6 +43705,38 @@ const useTitleStyles = makeStyles((theme) => ({
43699
43705
  }
43700
43706
  }
43701
43707
  }));
43708
+ function arrayToString(arr) {
43709
+ const arrF = arr.filter((item) => item !== void 0);
43710
+ if (arrF.length === 0) {
43711
+ return "";
43712
+ }
43713
+ if (arrF.length === 1) {
43714
+ return arrF[0];
43715
+ }
43716
+ return `${arr.slice(0, -1).join(", ")} and ${arr.slice(-1)}`;
43717
+ }
43718
+ const ViewTypesToText = /* @__PURE__ */ new Map([
43719
+ [ViewType$1.DESCRIPTION, "description"],
43720
+ [ViewType$1.STATUS, "status view for debugging"],
43721
+ [ViewType$1.SCATTERPLOT, "scatterplot with embeddings"],
43722
+ [ViewType$1.SPATIAL, "spatial view"],
43723
+ [ViewType$1.SPATIAL_BETA, "spatial view"],
43724
+ [ViewType$1.HEATMAP, "cell by gene heatmap"],
43725
+ [ViewType$1.LAYER_CONTROLLER, "layer controller"],
43726
+ [ViewType$1.LAYER_CONTROLLER_BETA, "layer controller"],
43727
+ [ViewType$1.GENOMIC_PROFILES, "genome browser tracks with bar plots"],
43728
+ [ViewType$1.GATING, "scatterplot of gated gene expression data"],
43729
+ [ViewType$1.FEATURE_LIST, "interactive list of features"],
43730
+ [ViewType$1.OBS_SETS, "list of potential observation sets"],
43731
+ [ViewType$1.OBS_SET_SIZES, "sizes of selected observation sets"],
43732
+ [ViewType$1.OBS_SET_FEATURE_VALUE_DISTRIBUTION, "violin plot with values"],
43733
+ [ViewType$1.FEATURE_VALUE_HISTOGRAM, "distribution of values"]
43734
+ ]);
43735
+ function getAltText(config2) {
43736
+ const componentList = config2.layout.map((c) => c.component);
43737
+ const altText = `Vitessce grid with ${componentList.length} views, including ${arrayToString(componentList.map((c) => ViewTypesToText.get(c) || "plugin view"))}.`;
43738
+ return altText;
43739
+ }
43702
43740
  const padding = 10;
43703
43741
  const margin = 5;
43704
43742
  function VitessceGrid(props) {
@@ -43719,6 +43757,7 @@ function VitessceGrid(props) {
43719
43757
  const [componentWidth] = useClosestVitessceContainerSize(containerRef);
43720
43758
  const classes = useVitessceContainerStyles();
43721
43759
  const titleClasses = useTitleStyles();
43760
+ const altText = useMemo(() => getAltText(config2), [configKey]);
43722
43761
  useEffect(() => {
43723
43762
  onResize();
43724
43763
  }, [rowHeight, onResize]);
@@ -43753,9 +43792,12 @@ function VitessceGrid(props) {
43753
43792
  {
43754
43793
  ref: containerRef,
43755
43794
  className: clsx(VITESSCE_CONTAINER, classes.vitessceContainer),
43795
+ role: "group",
43796
+ "aria-label": altText,
43756
43797
  children: layout2 ? /* @__PURE__ */ jsxRuntimeExports.jsx(
43757
43798
  VitessceGridLayout,
43758
43799
  {
43800
+ role: "group",
43759
43801
  layout: layout2,
43760
43802
  height: height2,
43761
43803
  rowHeight,
@@ -1 +1 @@
1
- {"version":3,"file":"VitessceGrid.d.ts","sourceRoot":"","sources":["../src/VitessceGrid.js"],"names":[],"mappings":"AA0BA;;;;;;;;;;;GAWG;AACH;IATyB,SAAS,EAAvB,MAAM;IACQ,MAAM,EAApB,MAAM;IACQ,KAAK,EAAnB,MAAM;IACQ,MAAM,EAApB,MAAM;IACU,MAAM;IACE,SAAS,EAAjC,gBAAgB;IACQ,SAAS,EAAjC,gBAAgB;IACgB,iBAAiB,EAAjD,wBAAwB;gBAuFlC"}
1
+ {"version":3,"file":"VitessceGrid.d.ts","sourceRoot":"","sources":["../src/VitessceGrid.js"],"names":[],"mappings":"AA4BA;;;;;;;;;;;GAWG;AACH;IATyB,SAAS,EAAvB,MAAM;IACQ,MAAM,EAApB,MAAM;IACQ,KAAK,EAAnB,MAAM;IACQ,MAAM,EAApB,MAAM;IACU,MAAM;IACE,SAAS,EAAjC,gBAAgB;IACQ,SAAS,EAAjC,gBAAgB;IACgB,iBAAiB,EAAjD,wBAAwB;gBA4FlC"}
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import React, { useEffect, useCallback, } from 'react';
2
+ import React, { useEffect, useCallback, useMemo, } from 'react';
3
3
  import clsx from 'clsx';
4
4
  import { VITESSCE_CONTAINER } from './classNames.js';
5
5
  import { VitessceGridLayout } from './vitessce-grid-layout/index.js';
@@ -8,6 +8,7 @@ import { useViewConfigStoreApi, useSetViewConfig, useSetLoaders, useEmitGridResi
8
8
  import { useClosestVitessceContainerSize, } from './hooks.js';
9
9
  import { useVitessceContainerStyles } from './shared-mui/container.js';
10
10
  import { useTitleStyles } from './title-styles.js';
11
+ import { getAltText } from './generate-alt-text.js';
11
12
  const padding = 10;
12
13
  const margin = 5;
13
14
  /**
@@ -29,6 +30,7 @@ export default function VitessceGrid(props) {
29
30
  const [componentWidth] = useClosestVitessceContainerSize(containerRef);
30
31
  const classes = useVitessceContainerStyles();
31
32
  const titleClasses = useTitleStyles();
33
+ const altText = useMemo(() => getAltText(config), [configKey]);
32
34
  // When the row height has changed, publish a GRID_RESIZE event.
33
35
  useEffect(() => {
34
36
  onResize();
@@ -59,5 +61,5 @@ export default function VitessceGrid(props) {
59
61
  setLoaders(newLoaders);
60
62
  // eslint-disable-next-line react-hooks/exhaustive-deps
61
63
  }, [success, configKey]);
62
- return (_jsx("div", { ref: containerRef, className: clsx(VITESSCE_CONTAINER, classes.vitessceContainer), children: layout ? (_jsx(VitessceGridLayout, { layout: layout, height: height, rowHeight: rowHeight, theme: theme, viewTypes: viewTypes, draggableHandle: titleClasses.title, margin: margin, padding: padding, onRemoveComponent: removeComponent, onLayoutChange: changeLayoutPostMount, isBounded: isBounded, onResize: onResize, onResizeStop: onResize })) : null }));
64
+ return (_jsx("div", { ref: containerRef, className: clsx(VITESSCE_CONTAINER, classes.vitessceContainer), role: "group", "aria-label": altText, children: layout ? (_jsx(VitessceGridLayout, { role: "group", layout: layout, height: height, rowHeight: rowHeight, theme: theme, viewTypes: viewTypes, draggableHandle: titleClasses.title, margin: margin, padding: padding, onRemoveComponent: removeComponent, onLayoutChange: changeLayoutPostMount, isBounded: isBounded, onResize: onResize, onResizeStop: onResize })) : null }));
63
65
  }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Method for converting an array with strings to a natural sentence,
3
+ * concatenating the items with commans, and the last item with 'and'.
4
+ * @param {Array} arr Array with text items.
5
+ * @returns {string} Natural language sentence in the form of 'a, b and c', where a/b/c are items.
6
+ */
7
+ export function arrayToString(arr: any[]): string;
8
+ /**
9
+ * Method for converting an array with strings to a natural sentence,
10
+ * concatenating the items with commans, and the last item with 'and'.
11
+ * @param {Object} config Vitessce config.
12
+ * @returns {string} Natural language sentence describing config (alt-text).
13
+ */
14
+ export function getAltText(config: Object): string;
15
+ /**
16
+ * Mapping of ViewType to natural language description of ViewType.
17
+ */
18
+ export const ViewTypesToText: Map<string, string>;
19
+ //# sourceMappingURL=generate-alt-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-alt-text.d.ts","sourceRoot":"","sources":["../src/generate-alt-text.js"],"names":[],"mappings":"AAEA;;;;;KAKK;AACL,2CAFe,MAAM,CAWpB;AAuBD;;;;;KAKK;AACL,mCAHa,MAAM,GACJ,MAAM,CAMpB;AA/BD;;KAEK;AACL,kDAgBG"}
@@ -0,0 +1,48 @@
1
+ import { ViewType } from '@vitessce/constants-internal';
2
+ /**
3
+ * Method for converting an array with strings to a natural sentence,
4
+ * concatenating the items with commans, and the last item with 'and'.
5
+ * @param {Array} arr Array with text items.
6
+ * @returns {string} Natural language sentence in the form of 'a, b and c', where a/b/c are items.
7
+ */
8
+ export function arrayToString(arr) {
9
+ const arrF = arr.filter(item => item !== undefined);
10
+ if (arrF.length === 0) {
11
+ return '';
12
+ }
13
+ if (arrF.length === 1) {
14
+ return arrF[0];
15
+ }
16
+ return `${arr.slice(0, -1).join(', ')} and ${arr.slice(-1)}`;
17
+ }
18
+ /**
19
+ * Mapping of ViewType to natural language description of ViewType.
20
+ */
21
+ export const ViewTypesToText = new Map([
22
+ [ViewType.DESCRIPTION, 'description'],
23
+ [ViewType.STATUS, 'status view for debugging'],
24
+ [ViewType.SCATTERPLOT, 'scatterplot with embeddings'],
25
+ [ViewType.SPATIAL, 'spatial view'],
26
+ [ViewType.SPATIAL_BETA, 'spatial view'],
27
+ [ViewType.HEATMAP, 'cell by gene heatmap'],
28
+ [ViewType.LAYER_CONTROLLER, 'layer controller'],
29
+ [ViewType.LAYER_CONTROLLER_BETA, 'layer controller'],
30
+ [ViewType.GENOMIC_PROFILES, 'genome browser tracks with bar plots'],
31
+ [ViewType.GATING, 'scatterplot of gated gene expression data'],
32
+ [ViewType.FEATURE_LIST, 'interactive list of features'],
33
+ [ViewType.OBS_SETS, 'list of potential observation sets'],
34
+ [ViewType.OBS_SET_SIZES, 'sizes of selected observation sets'],
35
+ [ViewType.OBS_SET_FEATURE_VALUE_DISTRIBUTION, 'violin plot with values'],
36
+ [ViewType.FEATURE_VALUE_HISTOGRAM, 'distribution of values'],
37
+ ]);
38
+ /**
39
+ * Method for converting an array with strings to a natural sentence,
40
+ * concatenating the items with commans, and the last item with 'and'.
41
+ * @param {Object} config Vitessce config.
42
+ * @returns {string} Natural language sentence describing config (alt-text).
43
+ */
44
+ export function getAltText(config) {
45
+ const componentList = config.layout.map(c => c.component);
46
+ const altText = `Vitessce grid with ${componentList.length} views, including ${arrayToString(componentList.map(c => ViewTypesToText.get(c) || 'plugin view'))}.`;
47
+ return altText;
48
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=generate-alt-text.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-alt-text.test.d.ts","sourceRoot":"","sources":["../src/generate-alt-text.test.js"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { ViewType } from '@vitessce/constants-internal';
3
+ import { arrayToString, ViewTypesToText, getAltText } from './generate-alt-text.js';
4
+ describe('Tests for generating an alt text from the vitessce config', () => {
5
+ describe('Tests for arrayToString', () => {
6
+ it('should return empty string for empty array', () => {
7
+ const arr = [];
8
+ const str = arrayToString(arr);
9
+ expect(str).toEqual('');
10
+ });
11
+ it('should return the element if the araay only has one element', () => {
12
+ const arr = ['one'];
13
+ const str = arrayToString(arr);
14
+ expect(str).toEqual('one');
15
+ });
16
+ it('should return the elements concatenated with "and" when the array has two elements', () => {
17
+ const arr = ['one', 'two'];
18
+ const str = arrayToString(arr);
19
+ expect(str).toEqual('one and two');
20
+ });
21
+ it('should return the elements concatenated with ", " and the last two elements with "and" when the array has more than two elements', () => {
22
+ const arr = ['one', 'two', 'three', 'four'];
23
+ const str = arrayToString(arr);
24
+ expect(str).toEqual('one, two, three and four');
25
+ });
26
+ });
27
+ describe('Tests for (const) ViewTypesToText', () => {
28
+ it('should have a natural language mapping for every defined viewtype', () => {
29
+ expect(ViewTypesToText.length).toEqual(ViewType.length);
30
+ });
31
+ });
32
+ describe('Tests for getAltTest', () => {
33
+ const config = {
34
+ coordinationSpace: {},
35
+ datasets: {},
36
+ description: 'Spatial organization of the somatosensory cortex revealed by osmFISH',
37
+ initStrategy: 'auto',
38
+ layout: [
39
+ { component: 'description', props: { description: 'Codeluppi et al., Nature Methods 2018: Spatial organization of the somatosensory cortex revealed by osmFISH' }, x: 0, y: 0, w: 2 },
40
+ { component: 'layerController', x: 0, y: 1, w: 2, h: 4 },
41
+ { component: 'status', x: 0, y: 5, w: 2, h: 1 },
42
+ { component: 'spatial', props: { channelNamesVisible: true }, x: 2, y: 0, w: 4 },
43
+ { component: 'featureList', x: 9, y: 0, w: 3, h: 2 },
44
+ { component: 'obsSets', x: 9, y: 3, w: 3, h: 2 },
45
+ { component: 'heatmap', props: { transpose: true }, x: 2, y: 4, w: 5 },
46
+ { component: 'obsSetFeatureValueDistribution', x: 7, y: 4, w: 5, h: 2 },
47
+ { component: 'scatterplot', x: 6, y: 0, w: 3, h: 2 },
48
+ { component: 'scatterplot', x: 6, y: 2, w: 3, h: 2 },
49
+ ],
50
+ name: 'Codeluppi et al., Nature Methods 2018',
51
+ uid: 'A',
52
+ version: '1.0.16',
53
+ };
54
+ const altText = getAltText(config);
55
+ it('should return a string', () => {
56
+ expect(typeof altText).toEqual('string');
57
+ });
58
+ it('should contain the number of views', () => {
59
+ const hasNViews = altText.includes('10');
60
+ expect(hasNViews).toEqual(true);
61
+ });
62
+ it('should contain mappings', () => {
63
+ const hasHeatmap = altText.includes('heatmap') && altText.includes('spatial') && altText.includes('description') && altText.includes('scatterplot');
64
+ expect(hasHeatmap).toEqual(true);
65
+ });
66
+ });
67
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitessce/vit-s",
3
- "version": "3.2.1",
3
+ "version": "3.2.2",
4
4
  "author": "Gehlenborg Lab",
5
5
  "homepage": "http://vitessce.io",
6
6
  "repository": {
@@ -29,10 +29,10 @@
29
29
  "uuid": "^9.0.0",
30
30
  "zustand": "^3.5.10",
31
31
  "react-aria": "^3.28.0",
32
- "@vitessce/constants-internal": "3.2.1",
33
- "@vitessce/schemas": "3.2.1",
34
- "@vitessce/plugins": "3.2.1",
35
- "@vitessce/utils": "3.2.1"
32
+ "@vitessce/constants-internal": "3.2.2",
33
+ "@vitessce/plugins": "3.2.2",
34
+ "@vitessce/schemas": "3.2.2",
35
+ "@vitessce/utils": "3.2.2"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@testing-library/jest-dom": "^5.16.4",
@@ -1,6 +1,7 @@
1
1
  import React, {
2
2
  useEffect,
3
3
  useCallback,
4
+ useMemo,
4
5
  } from 'react';
5
6
  import clsx from 'clsx';
6
7
  import { VITESSCE_CONTAINER } from './classNames.js';
@@ -20,6 +21,7 @@ import {
20
21
  } from './hooks.js';
21
22
  import { useVitessceContainerStyles } from './shared-mui/container.js';
22
23
  import { useTitleStyles } from './title-styles.js';
24
+ import { getAltText } from './generate-alt-text.js';
23
25
 
24
26
  const padding = 10;
25
27
  const margin = 5;
@@ -58,6 +60,8 @@ export default function VitessceGrid(props) {
58
60
  const classes = useVitessceContainerStyles();
59
61
  const titleClasses = useTitleStyles();
60
62
 
63
+ const altText = useMemo(() => getAltText(config), [configKey]);
64
+
61
65
  // When the row height has changed, publish a GRID_RESIZE event.
62
66
  useEffect(() => {
63
67
  onResize();
@@ -101,9 +105,12 @@ export default function VitessceGrid(props) {
101
105
  <div
102
106
  ref={containerRef}
103
107
  className={clsx(VITESSCE_CONTAINER, classes.vitessceContainer)}
108
+ role="group"
109
+ aria-label={altText}
104
110
  >
105
111
  {layout ? (
106
112
  <VitessceGridLayout
113
+ role="group"
107
114
  layout={layout}
108
115
  height={height}
109
116
  rowHeight={rowHeight}
@@ -0,0 +1,51 @@
1
+ import { ViewType } from '@vitessce/constants-internal';
2
+
3
+ /**
4
+ * Method for converting an array with strings to a natural sentence,
5
+ * concatenating the items with commans, and the last item with 'and'.
6
+ * @param {Array} arr Array with text items.
7
+ * @returns {string} Natural language sentence in the form of 'a, b and c', where a/b/c are items.
8
+ */
9
+ export function arrayToString(arr) {
10
+ const arrF = arr.filter(item => item !== undefined);
11
+ if (arrF.length === 0) {
12
+ return '';
13
+ }
14
+ if (arrF.length === 1) {
15
+ return arrF[0];
16
+ }
17
+ return `${arr.slice(0, -1).join(', ')} and ${arr.slice(-1)}`;
18
+ }
19
+
20
+ /**
21
+ * Mapping of ViewType to natural language description of ViewType.
22
+ */
23
+ export const ViewTypesToText = new Map([
24
+ [ViewType.DESCRIPTION, 'description'],
25
+ [ViewType.STATUS, 'status view for debugging'],
26
+ [ViewType.SCATTERPLOT, 'scatterplot with embeddings'],
27
+ [ViewType.SPATIAL, 'spatial view'],
28
+ [ViewType.SPATIAL_BETA, 'spatial view'],
29
+ [ViewType.HEATMAP, 'cell by gene heatmap'],
30
+ [ViewType.LAYER_CONTROLLER, 'layer controller'],
31
+ [ViewType.LAYER_CONTROLLER_BETA, 'layer controller'],
32
+ [ViewType.GENOMIC_PROFILES, 'genome browser tracks with bar plots'],
33
+ [ViewType.GATING, 'scatterplot of gated gene expression data'],
34
+ [ViewType.FEATURE_LIST, 'interactive list of features'],
35
+ [ViewType.OBS_SETS, 'list of potential observation sets'],
36
+ [ViewType.OBS_SET_SIZES, 'sizes of selected observation sets'],
37
+ [ViewType.OBS_SET_FEATURE_VALUE_DISTRIBUTION, 'violin plot with values'],
38
+ [ViewType.FEATURE_VALUE_HISTOGRAM, 'distribution of values'],
39
+ ]);
40
+
41
+ /**
42
+ * Method for converting an array with strings to a natural sentence,
43
+ * concatenating the items with commans, and the last item with 'and'.
44
+ * @param {Object} config Vitessce config.
45
+ * @returns {string} Natural language sentence describing config (alt-text).
46
+ */
47
+ export function getAltText(config) {
48
+ const componentList = config.layout.map(c => c.component);
49
+ const altText = `Vitessce grid with ${componentList.length} views, including ${arrayToString(componentList.map(c => ViewTypesToText.get(c) || 'plugin view'))}.`;
50
+ return altText;
51
+ }
@@ -0,0 +1,73 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { ViewType } from '@vitessce/constants-internal';
3
+ import { arrayToString, ViewTypesToText, getAltText } from './generate-alt-text.js';
4
+
5
+ describe('Tests for generating an alt text from the vitessce config', () => {
6
+ describe('Tests for arrayToString', () => {
7
+ it('should return empty string for empty array', () => {
8
+ const arr = [];
9
+ const str = arrayToString(arr);
10
+ expect(str).toEqual('');
11
+ });
12
+
13
+ it('should return the element if the araay only has one element', () => {
14
+ const arr = ['one'];
15
+ const str = arrayToString(arr);
16
+ expect(str).toEqual('one');
17
+ });
18
+
19
+ it('should return the elements concatenated with "and" when the array has two elements', () => {
20
+ const arr = ['one', 'two'];
21
+ const str = arrayToString(arr);
22
+ expect(str).toEqual('one and two');
23
+ });
24
+
25
+ it('should return the elements concatenated with ", " and the last two elements with "and" when the array has more than two elements', () => {
26
+ const arr = ['one', 'two', 'three', 'four'];
27
+ const str = arrayToString(arr);
28
+ expect(str).toEqual('one, two, three and four');
29
+ });
30
+ });
31
+
32
+ describe('Tests for (const) ViewTypesToText', () => {
33
+ it('should have a natural language mapping for every defined viewtype', () => {
34
+ expect(ViewTypesToText.length).toEqual(ViewType.length);
35
+ });
36
+ });
37
+
38
+ describe('Tests for getAltTest', () => {
39
+ const config = {
40
+ coordinationSpace: {},
41
+ datasets: {},
42
+ description: 'Spatial organization of the somatosensory cortex revealed by osmFISH',
43
+ initStrategy: 'auto',
44
+ layout: [
45
+ { component: 'description', props: { description: 'Codeluppi et al., Nature Methods 2018: Spatial organization of the somatosensory cortex revealed by osmFISH' }, x: 0, y: 0, w: 2 },
46
+ { component: 'layerController', x: 0, y: 1, w: 2, h: 4 },
47
+ { component: 'status', x: 0, y: 5, w: 2, h: 1 },
48
+ { component: 'spatial', props: { channelNamesVisible: true }, x: 2, y: 0, w: 4 },
49
+ { component: 'featureList', x: 9, y: 0, w: 3, h: 2 },
50
+ { component: 'obsSets', x: 9, y: 3, w: 3, h: 2 },
51
+ { component: 'heatmap', props: { transpose: true }, x: 2, y: 4, w: 5 },
52
+ { component: 'obsSetFeatureValueDistribution', x: 7, y: 4, w: 5, h: 2 },
53
+ { component: 'scatterplot', x: 6, y: 0, w: 3, h: 2 },
54
+ { component: 'scatterplot', x: 6, y: 2, w: 3, h: 2 },
55
+ ],
56
+ name: 'Codeluppi et al., Nature Methods 2018',
57
+ uid: 'A',
58
+ version: '1.0.16',
59
+ };
60
+ const altText = getAltText(config);
61
+ it('should return a string', () => {
62
+ expect(typeof altText).toEqual('string');
63
+ });
64
+ it('should contain the number of views', () => {
65
+ const hasNViews = altText.includes('10');
66
+ expect(hasNViews).toEqual(true);
67
+ });
68
+ it('should contain mappings', () => {
69
+ const hasHeatmap = altText.includes('heatmap') && altText.includes('spatial') && altText.includes('description') && altText.includes('scatterplot');
70
+ expect(hasHeatmap).toEqual(true);
71
+ });
72
+ });
73
+ });