@opentrons/shared-data 0.0.1-alpha.20 → 0.0.1-alpha.21

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.
Files changed (151) hide show
  1. package/package.json +1 -1
  2. package/js/__tests__/__snapshots__/pipettes.test.ts.snap +0 -5969
  3. package/js/__tests__/deckSchemas.test.ts +0 -87
  4. package/js/__tests__/errors.test.js +0 -21
  5. package/js/__tests__/getAreSlotsAdjacent.test.ts +0 -128
  6. package/js/__tests__/getWellNamePerMultiTip.test.ts +0 -162
  7. package/js/__tests__/labwareDefQuirks.test.ts +0 -37
  8. package/js/__tests__/labwareDefSchemaV1.test.ts +0 -82
  9. package/js/__tests__/labwareDefSchemaV2.test.ts +0 -298
  10. package/js/__tests__/moduleAccessors.test.ts +0 -50
  11. package/js/__tests__/moduleSpecsSchema.test.ts +0 -77
  12. package/js/__tests__/pipetteSchemaV2.test.ts +0 -107
  13. package/js/__tests__/pipetteSpecSchemas.test.ts +0 -48
  14. package/js/__tests__/pipettes.test.ts +0 -58
  15. package/js/__tests__/protocolSchemaV4.test.ts +0 -137
  16. package/js/__tests__/protocolSchemaV5.test.ts +0 -137
  17. package/js/__tests__/protocolSchemaV6.test.ts +0 -132
  18. package/js/__tests__/protocolSchemaV7.test.ts +0 -64
  19. package/js/__tests__/protocolValidation.test.ts +0 -83
  20. package/js/__tests__/sortWells.test.ts +0 -40
  21. package/js/__tests__/splitWellsOnColumn.test.ts +0 -21
  22. package/js/__tests__/validateErrors.test.js +0 -34
  23. package/js/constants.ts +0 -338
  24. package/js/cypressUtils.ts +0 -35
  25. package/js/errors.ts +0 -33
  26. package/js/fixtures.ts +0 -161
  27. package/js/getLabware.ts +0 -154
  28. package/js/gripper.ts +0 -29
  29. package/js/helpers/__tests__/getAdapterName.test.ts +0 -31
  30. package/js/helpers/__tests__/getDeckDefFromLoadedLabware.test.ts +0 -12
  31. package/js/helpers/__tests__/getVectorDifference.test.ts +0 -25
  32. package/js/helpers/__tests__/getVectorSum.test.ts +0 -21
  33. package/js/helpers/__tests__/labwareInference.test.ts +0 -84
  34. package/js/helpers/__tests__/orderWells.test.ts +0 -87
  35. package/js/helpers/__tests__/parseProtocolData.test.ts +0 -165
  36. package/js/helpers/__tests__/volume.test.ts +0 -108
  37. package/js/helpers/__tests__/wellSets.test.ts +0 -352
  38. package/js/helpers/get96Channel384WellPlateWells.ts +0 -44
  39. package/js/helpers/getAddressableAreasInProtocol.ts +0 -59
  40. package/js/helpers/getLoadedLabwareDefinitionsByUri.ts +0 -30
  41. package/js/helpers/getModuleVizDims.ts +0 -118
  42. package/js/helpers/getOccludedSlotCountForModule.ts +0 -13
  43. package/js/helpers/getVectorDifference.ts +0 -12
  44. package/js/helpers/getVectorSum.ts +0 -12
  45. package/js/helpers/getWellNamePerMultiTip.ts +0 -86
  46. package/js/helpers/getWellTotalVolume.ts +0 -16
  47. package/js/helpers/index.ts +0 -347
  48. package/js/helpers/labwareInference.ts +0 -92
  49. package/js/helpers/orderWells.ts +0 -69
  50. package/js/helpers/parseProtocolData.ts +0 -141
  51. package/js/helpers/volume.ts +0 -35
  52. package/js/helpers/wellIsRect.ts +0 -6
  53. package/js/helpers/wellSets.ts +0 -155
  54. package/js/index.ts +0 -14
  55. package/js/labwareTools/__tests__/__snapshots__/createIrregularLabware.test.ts.snap +0 -3
  56. package/js/labwareTools/__tests__/__snapshots__/createLabware.test.ts.snap +0 -3
  57. package/js/labwareTools/__tests__/createDefaultDisplayName.test.ts +0 -111
  58. package/js/labwareTools/__tests__/createIrregularLabware.test.ts +0 -226
  59. package/js/labwareTools/__tests__/createLabware.test.ts +0 -147
  60. package/js/labwareTools/index.ts +0 -452
  61. package/js/modules.ts +0 -97
  62. package/js/pipettes.ts +0 -89
  63. package/js/protocols.ts +0 -290
  64. package/js/schema.ts +0 -80
  65. package/js/scripts/generateDeckLayersFromSVG.js +0 -46
  66. package/js/titleCase.ts +0 -30
  67. package/js/types.ts +0 -600
  68. package/python/.coveragerc +0 -4
  69. package/python/.flake8 +0 -32
  70. package/python/Config.in +0 -10
  71. package/python/Makefile +0 -134
  72. package/python/Pipfile +0 -28
  73. package/python/Pipfile.lock +0 -645
  74. package/python/buildroot.mk +0 -30
  75. package/python/mypy.ini +0 -41
  76. package/python/opentrons_shared_data/__init__.py +0 -17
  77. package/python/opentrons_shared_data/_version.py +0 -20
  78. package/python/opentrons_shared_data/command/__init__.py +0 -52
  79. package/python/opentrons_shared_data/deck/__init__.py +0 -96
  80. package/python/opentrons_shared_data/deck/dev_types.py +0 -180
  81. package/python/opentrons_shared_data/errors/__init__.py +0 -30
  82. package/python/opentrons_shared_data/errors/categories.py +0 -60
  83. package/python/opentrons_shared_data/errors/codes.py +0 -108
  84. package/python/opentrons_shared_data/errors/exceptions.py +0 -915
  85. package/python/opentrons_shared_data/gripper/__init__.py +0 -63
  86. package/python/opentrons_shared_data/gripper/constants.py +0 -6
  87. package/python/opentrons_shared_data/gripper/gripper_definition.py +0 -101
  88. package/python/opentrons_shared_data/labware/__init__.py +0 -22
  89. package/python/opentrons_shared_data/labware/constants.py +0 -7
  90. package/python/opentrons_shared_data/labware/dev_types.py +0 -140
  91. package/python/opentrons_shared_data/labware/labware_definition.py +0 -328
  92. package/python/opentrons_shared_data/load.py +0 -57
  93. package/python/opentrons_shared_data/module/__init__.py +0 -74
  94. package/python/opentrons_shared_data/module/dev_types.py +0 -141
  95. package/python/opentrons_shared_data/pipette/__init__.py +0 -107
  96. package/python/opentrons_shared_data/pipette/dev_types.py +0 -177
  97. package/python/opentrons_shared_data/pipette/file_operation_helpers.py +0 -37
  98. package/python/opentrons_shared_data/pipette/load_data.py +0 -261
  99. package/python/opentrons_shared_data/pipette/model_constants.py +0 -123
  100. package/python/opentrons_shared_data/pipette/mutable_configurations.py +0 -431
  101. package/python/opentrons_shared_data/pipette/pipette_definition.py +0 -503
  102. package/python/opentrons_shared_data/pipette/pipette_load_name_conversions.py +0 -240
  103. package/python/opentrons_shared_data/pipette/scripts/__init__.py +0 -0
  104. package/python/opentrons_shared_data/pipette/scripts/build_json_script.py +0 -469
  105. package/python/opentrons_shared_data/pipette/scripts/update_configuration_files.py +0 -450
  106. package/python/opentrons_shared_data/pipette/types.py +0 -193
  107. package/python/opentrons_shared_data/protocol/__init__.py +0 -13
  108. package/python/opentrons_shared_data/protocol/constants.py +0 -98
  109. package/python/opentrons_shared_data/protocol/dev_types.py +0 -436
  110. package/python/opentrons_shared_data/protocol/models/__init__.py +0 -48
  111. package/python/opentrons_shared_data/protocol/models/protocol_schema_v6.py +0 -145
  112. package/python/opentrons_shared_data/protocol/models/protocol_schema_v7.py +0 -95
  113. package/python/opentrons_shared_data/protocol/models/protocol_schema_v8.py +0 -110
  114. package/python/opentrons_shared_data/protocol/models/shared_models.py +0 -111
  115. package/python/opentrons_shared_data/py.typed +0 -0
  116. package/python/opentrons_shared_data/robot/__init__.py +0 -33
  117. package/python/opentrons_shared_data/robot/dev_types.py +0 -37
  118. package/python/pytest.ini +0 -2
  119. package/python/setup.cfg +0 -5
  120. package/python/setup.py +0 -179
  121. package/python/tests/__init__.py +0 -1
  122. package/python/tests/conftest.py +0 -0
  123. package/python/tests/deck/__init__.py +0 -0
  124. package/python/tests/deck/test_list_names.py +0 -12
  125. package/python/tests/deck/test_position.py +0 -113
  126. package/python/tests/deck/test_typechecks.py +0 -28
  127. package/python/tests/errors/__init__.py +0 -1
  128. package/python/tests/errors/test_error_completeness.py +0 -19
  129. package/python/tests/errors/test_exceptions.py +0 -74
  130. package/python/tests/gripper/__init__.py +0 -0
  131. package/python/tests/gripper/test_definition.py +0 -30
  132. package/python/tests/gripper/test_load.py +0 -16
  133. package/python/tests/labware/__init__.py +0 -13
  134. package/python/tests/labware/test_typechecks.py +0 -21
  135. package/python/tests/module/__init__.py +0 -20
  136. package/python/tests/module/test_load.py +0 -49
  137. package/python/tests/module/test_typechecks.py +0 -34
  138. package/python/tests/pipette/__init__.py +0 -0
  139. package/python/tests/pipette/test_load_data.py +0 -103
  140. package/python/tests/pipette/test_mutable_configurations.py +0 -266
  141. package/python/tests/pipette/test_pipette_definition.py +0 -183
  142. package/python/tests/pipette/test_pipette_load_name_conversions.py +0 -222
  143. package/python/tests/pipette/test_typechecks.py +0 -50
  144. package/python/tests/pipette/test_validate_schema.py +0 -37
  145. package/python/tests/protocol/__init__.py +0 -15
  146. package/python/tests/protocol/test_protocol_schema_v6.py +0 -107
  147. package/python/tests/protocol/test_protocol_schema_v7.py +0 -34
  148. package/python/tests/protocol/test_protocol_schema_v8.py +0 -20
  149. package/python/tests/protocol/test_typechecks.py +0 -36
  150. package/python/tests/robot/__init__.py +0 -0
  151. package/python/tests/robot/test_typechecks.py +0 -20
package/js/getLabware.ts DELETED
@@ -1,154 +0,0 @@
1
- import mapValues from 'lodash/mapValues'
2
-
3
- import {
4
- FIXED_TRASH_RENDER_HEIGHT,
5
- OPENTRONS_LABWARE_NAMESPACE,
6
- SLOT_RENDER_HEIGHT,
7
- } from './constants'
8
-
9
- import type {
10
- LabwareDefinition1,
11
- LabwareDefinition2,
12
- WellDefinition,
13
- } from './types'
14
-
15
- // do not list in any "available labware" UI.
16
- // TODO(mc, 2019-12-3): how should this correspond to RETIRED_LABWARE?
17
- // see shared-data/js/helpers/index.js
18
- export const LABWAREV2_DO_NOT_LIST = [
19
- // Labware definitions only used for back-compat with legacy v1 defs:
20
- 'opentrons_40_aluminumblock_eppendorf_24x2ml_safelock_snapcap_generic_16x0.2ml_pcr_strip',
21
- 'opentrons_24_tuberack_eppendorf_2ml_safelock_snapcap_acrylic',
22
- 'opentrons_24_tuberack_generic_0.75ml_snapcap_acrylic',
23
- 'opentrons_10_tuberack_falcon_4x50ml_6x15ml_conical_acrylic',
24
- 'tipone_96_tiprack_200ul',
25
- 'eppendorf_96_tiprack_1000ul_eptips',
26
- 'eppendorf_96_tiprack_10ul_eptips',
27
- // Replaced by opentrons_96_wellplate_200ul_pcr_full_skirt
28
- // (https://opentrons.atlassian.net/browse/RLAB-230):
29
- 'armadillo_96_wellplate_200ul_pcr_full_skirt',
30
- 'opentrons_96_pcr_adapter_armadillo_wellplate_200ul',
31
- // Special labware that users probably shouldn't know about or load:
32
- // these all should eventually be given a new namespace like "opentrons-internal"
33
- // so that they can be filtered out by namespace rather than a block list like this
34
- 'opentrons_1_trash_850ml_fixed',
35
- 'opentrons_1_trash_1100ml_fixed',
36
- 'opentrons_1_trash_3200ml_fixed',
37
- 'opentrons_calibrationblock_short_side_left',
38
- 'opentrons_calibrationblock_short_side_right',
39
- 'opentrons_calibration_adapter_heatershaker_module',
40
- 'opentrons_calibration_adapter_temperature_module',
41
- 'opentrons_calibration_adapter_thermocycler_module',
42
- 'opentrons_ot3_96_tiprack_20ul',
43
- 'opentrons_ot3_96_tiprack_200ul',
44
- 'opentrons_ot3_96_tiprack_1000ul',
45
- 'opentrons_ot3_96_tiprack_50ul',
46
- ]
47
- // NOTE(sa, 2020-7-14): in PD we do not want to list calibration blocks
48
- // but we still might want the rest of the labware in LABWAREV2_DO_NOT_LIST
49
- // because of legacy protocols that might use them
50
- export const PD_DO_NOT_LIST = [
51
- 'opentrons_calibrationblock_short_side_left',
52
- 'opentrons_calibrationblock_short_side_right',
53
- 'opentrons_96_aluminumblock_biorad_wellplate_200ul',
54
- 'opentrons_96_aluminumblock_nest_wellplate_100ul',
55
- ]
56
-
57
- export function getLabwareV1Def(
58
- labwareName: string
59
- ): LabwareDefinition1 | null | undefined {
60
- const labware: LabwareDefinition1 | null | undefined =
61
- // @ts-expect-error(mc, 2021-04-27): make lookup more strict or remove v1 defs entirely
62
- definitions[labwareName]
63
- return labware
64
- }
65
-
66
- export function getIsLabwareV1Tiprack(def: LabwareDefinition1): boolean {
67
- return Boolean(def?.metadata?.isTiprack)
68
- }
69
-
70
- export function getIsTiprack(labwareDef: LabwareDefinition2): boolean {
71
- return labwareDef.parameters.isTiprack
72
- }
73
-
74
- // NOTE: these labware definitions in _SHORT_MM_LABWARE_DEF_LOADNAMES
75
- // were written in "short mm" = 0.5mm, but
76
- // we will write all future definitions in actual mm.
77
- // These allowed labware also have engage heights measured from home switch
78
- // instead of from labware bottom, which is why we add ENGAGE_HEIGHT_OFFSET.
79
- //
80
- // Ideally instead of using this allow-list, we would publish a new version
81
- // of these definitions with corrected labware heights. However, we don't
82
- // support labware versioning well enough yet.
83
- const _SHORT_MM_LABWARE_DEF_LOADNAMES = [
84
- 'biorad_96_wellplate_200ul_pcr',
85
- 'nest_96_wellplate_100ul_pcr_full_skirt',
86
- 'usascientific_96_wellplate_2.4ml_deep',
87
- ]
88
-
89
- // offset added to parameters.magneticModuleEngageHeight to convert older labware
90
- // definitions from "distance from home switch" to "distance from labware bottom"
91
- // Note: this is in actual mm, not "short mm" :)
92
- const ENGAGE_HEIGHT_OFFSET = -4
93
-
94
- export function getLabwareDefaultEngageHeight(
95
- labwareDef: LabwareDefinition2
96
- ): number | null {
97
- const rawEngageHeight: number | null | undefined =
98
- labwareDef.parameters.magneticModuleEngageHeight
99
-
100
- if (
101
- labwareDef.namespace === OPENTRONS_LABWARE_NAMESPACE &&
102
- _SHORT_MM_LABWARE_DEF_LOADNAMES.includes(labwareDef.parameters.loadName)
103
- ) {
104
- return rawEngageHeight == null
105
- ? null
106
- : rawEngageHeight / 2 + ENGAGE_HEIGHT_OFFSET
107
- }
108
-
109
- return rawEngageHeight == null ? null : rawEngageHeight
110
- }
111
-
112
- /* Render Helpers */
113
- // NOTE: this doesn't account for the differing footprints of labware
114
- // the fixed trash render height is the first bandaid to partially
115
- // mend this, but overall the labware definitions in shared-data are
116
- // insufficient to render labware at the resolution we'd like to
117
- // achieve going forward.
118
- // TODO: BC 2019-02-28 The height constants used here should be replaced with the heights
119
- // in the dimensions field of the corresponding labware in definitions
120
- const _getSvgYValueForWell = (
121
- def: LabwareDefinition1,
122
- wellDef: WellDefinition
123
- ): number => {
124
- const labwareName = def.metadata.name
125
- const renderHeight =
126
- labwareName === 'fixed-trash'
127
- ? FIXED_TRASH_RENDER_HEIGHT
128
- : SLOT_RENDER_HEIGHT
129
- return renderHeight - wellDef.y
130
- }
131
-
132
- /** For display. Flips Y axis to match SVG, applies offset to wells */
133
- export function getWellPropsForSVGLabwareV1(
134
- def: LabwareDefinition1
135
- ): Record<string, WellDefinition> {
136
- const wellDefs = def && def.wells
137
- // Most labware defs have a weird offset,
138
- // but tips are mostly OK.
139
- // This is a HACK to make the offset less "off"
140
- const isTiprack = getIsLabwareV1Tiprack(def)
141
- let xCorrection = 0
142
- let yCorrection = 0
143
-
144
- if (!isTiprack) {
145
- xCorrection = 1
146
- yCorrection = -3
147
- }
148
-
149
- return mapValues(wellDefs, (wellDef: WellDefinition) => ({
150
- ...wellDef,
151
- x: wellDef.x + xCorrection,
152
- y: _getSvgYValueForWell(def, wellDef) + yCorrection,
153
- }))
154
- }
package/js/gripper.ts DELETED
@@ -1,29 +0,0 @@
1
- import gripperV1 from '../gripper/definitions/1/gripperV1.json'
2
- import gripperV1_1 from '../gripper/definitions/1/gripperV1.1.json'
3
- import gripperV1_2 from '../gripper/definitions/1/gripperV1.2.json'
4
-
5
- import { GRIPPER_V1, GRIPPER_V1_1, GRIPPER_V1_2 } from './constants'
6
-
7
- import type { GripperModel, GripperDefinition } from './types'
8
-
9
- export const getGripperDef = (
10
- gripperModel: GripperModel
11
- ): GripperDefinition => {
12
- switch (gripperModel) {
13
- case GRIPPER_V1:
14
- return gripperV1 as GripperDefinition
15
- case GRIPPER_V1_1:
16
- return gripperV1_1 as GripperDefinition
17
- case GRIPPER_V1_2:
18
- return gripperV1_2 as GripperDefinition
19
- default:
20
- console.warn(
21
- `Could not find a gripper with model ${gripperModel}, falling back to most recent definition: ${GRIPPER_V1_1}`
22
- )
23
- return gripperV1_1 as GripperDefinition
24
- }
25
- }
26
-
27
- export function getGripperDisplayName(gripperModel: GripperModel): string {
28
- return getGripperDef(gripperModel).displayName
29
- }
@@ -1,31 +0,0 @@
1
- import { getAdapterName } from '../index'
2
-
3
- describe('getAdapterName', () => {
4
- it(`should return the PCR adapter name`, () => {
5
- expect(
6
- getAdapterName(
7
- 'opentrons_96_pcr_adapter_nest_wellplate_100ul_pcr_full_skirt'
8
- )
9
- ).toEqual('PCR Adapter')
10
- })
11
- it(`should return the Deep well adapter name`, () => {
12
- expect(
13
- getAdapterName('opentrons_96_deep_well_adapter_nest_wellplate_2ml_deep')
14
- ).toEqual('Deep Well Adapter')
15
- })
16
- it(`should return the 96 flat bottom adapter name`, () => {
17
- expect(
18
- getAdapterName(
19
- 'opentrons_96_flat_bottom_adapter_nest_wellplate_200ul_flat'
20
- )
21
- ).toEqual('96 Flat Bottom Adapter')
22
- })
23
- it(`should return universal flat adapter name when loadname is not 1 of the 3 specified loadnames`, () => {
24
- expect(
25
- getAdapterName(
26
- 'opentrons_universal_flat_adapter_corning_384_wellplate_112ul_flat'
27
- )
28
- ).toEqual('Universal Flat Adapter')
29
- expect(getAdapterName('random labware')).toEqual('Universal Flat Adapter')
30
- })
31
- })
@@ -1,12 +0,0 @@
1
- import ot2DeckDef from '../../../deck/definitions/4/ot2_standard.json'
2
- import ot3DeckDef from '../../../deck/definitions/4/ot3_standard.json'
3
- import { getDeckDefFromRobotType } from '..'
4
-
5
- describe('getDeckDefFromRobotType', () => {
6
- it('should return an OT-2 deck when the protocol is for an OT-2', () => {
7
- expect(getDeckDefFromRobotType('OT-2 Standard')).toBe(ot2DeckDef)
8
- })
9
- it('should return an OT-3 deck when the protocol is for an OT-3', () => {
10
- expect(getDeckDefFromRobotType('OT-3 Standard')).toBe(ot3DeckDef)
11
- })
12
- })
@@ -1,25 +0,0 @@
1
- import { getVectorDifference } from '../getVectorDifference'
2
-
3
- describe('getVectorDifference', () => {
4
- it(`should calculate difference betwen pointA and pointB with integer values`, () => {
5
- expect(
6
- getVectorDifference({ x: 1, y: 2, z: 3 }, { x: 1, y: 2, z: 3 })
7
- ).toEqual({ x: 0, y: 0, z: 0 })
8
- })
9
- it(`should calculate difference betwen pointA and pointB with decimal values`, () => {
10
- expect(
11
- getVectorDifference(
12
- { x: 1.0, y: 2.0, z: 3.0 },
13
- { x: 1.0, y: 2.0, z: 3.0 }
14
- )
15
- ).toEqual({ x: 0, y: 0, z: 0 })
16
- })
17
- it(`should calculate difference betwen pointA and pointB with mix of negative and positive`, () => {
18
- expect(
19
- getVectorDifference(
20
- { x: -1.0, y: -2.0, z: -3.0 },
21
- { x: 1.0, y: 2.0, z: 3.0 }
22
- )
23
- ).toEqual({ x: -2, y: -4, z: -6 })
24
- })
25
- })
@@ -1,21 +0,0 @@
1
- import { getVectorSum } from '../getVectorSum'
2
-
3
- describe('getVectorSum', () => {
4
- it(`should calculate sum betwen pointA and pointB with integer values`, () => {
5
- expect(getVectorSum({ x: 1, y: 2, z: 3 }, { x: 1, y: 2, z: 3 })).toEqual({
6
- x: 2,
7
- y: 4,
8
- z: 6,
9
- })
10
- })
11
- it(`should calculate sum betwen pointA and pointB with decimal values`, () => {
12
- expect(
13
- getVectorSum({ x: 1.0, y: 2.0, z: 3.0 }, { x: 1.0, y: 2.0, z: 3.0 })
14
- ).toEqual({ x: 2, y: 4, z: 6 })
15
- })
16
- it(`should calculate sum betwen pointA and pointB with mix of negative and positive`, () => {
17
- expect(
18
- getVectorSum({ x: -1.0, y: -2.0, z: -3.0 }, { x: 1.0, y: 2.0, z: 3.0 })
19
- ).toEqual({ x: 0, y: 0, z: 0 })
20
- })
21
- })
@@ -1,84 +0,0 @@
1
- import { getIfConsistent, getSpacingIfUniform } from '../labwareInference'
2
-
3
- describe('getSpacingIfUniform', () => {
4
- const testCases = [
5
- {
6
- testLabel: '1 well case: return 0',
7
- wells: [{ x: 10 }],
8
- expected: 0,
9
- },
10
- {
11
- testLabel: '2 well case',
12
- wells: [{ x: 10 }, { x: 20 }],
13
- expected: 10,
14
- },
15
- {
16
- testLabel:
17
- '2 well case with overlapping wells (eg, single-column labware): return 0',
18
- wells: [{ x: 10 }, { x: 10 }],
19
- expected: 0,
20
- },
21
- {
22
- testLabel: '3 well case',
23
- wells: [{ x: 0 }, { x: 25 }, { x: 50 }],
24
- expected: 25,
25
- },
26
- {
27
- testLabel:
28
- '3 well case with overlapping wells (eg, single-column labware): return 0',
29
- wells: [{ x: 10 }, { x: 10 }, { x: 10 }],
30
- expected: 0,
31
- },
32
- {
33
- testLabel: '3 well case: out of order is non-uniform, return null',
34
- wells: [{ x: 50 }, { x: 0 }, { x: 25 }],
35
- expected: null,
36
- },
37
- {
38
- testLabel: '3 well case: non-uniform with some duplicate values',
39
- wells: [
40
- { x: 0 },
41
- { x: 25 },
42
- { x: 25, spam: 'spam' },
43
- { x: 50 },
44
- { x: 50, foo: 'foo' },
45
- ],
46
- expected: 25,
47
- },
48
- {
49
- testLabel: 'returns null if wells have irregular spacing',
50
- wells: [{ x: 10 }, { x: 20 }, { x: 21 }],
51
- expected: null,
52
- },
53
- {
54
- testLabel: 'returns 0 with no wells',
55
- wells: [],
56
- expected: 0,
57
- },
58
- ]
59
- testCases.forEach(({ wells, expected, testLabel }) =>
60
- it(testLabel, () =>
61
- expect(getSpacingIfUniform(wells as any[], 'x')).toBe(expected)
62
- )
63
- )
64
- })
65
-
66
- describe('getIfConsistent', () => {
67
- it('deep equal', () => {
68
- const items = [
69
- { a: 123, b: [1, 2, [3]] },
70
- { a: 123, b: [1, 2, [3]] },
71
- { a: 123, b: [1, 2, [3]] },
72
- ]
73
- expect(getIfConsistent(items)).toEqual(items[0])
74
- })
75
-
76
- it('deep difference', () => {
77
- const items = [
78
- { a: 123, b: [1, 2, [3]] },
79
- { a: 123, b: [1, 2, [999999]] },
80
- { a: 123, b: [1, 2, [3]] },
81
- ]
82
- expect(getIfConsistent(items)).toBe(null)
83
- })
84
- })
@@ -1,87 +0,0 @@
1
- import { orderWells } from '../orderWells'
2
- import type { WellOrderOption } from '../orderWells'
3
-
4
- describe('orderWells', () => {
5
- const orderTuples: Array<[WellOrderOption, WellOrderOption]> = [
6
- ['t2b', 'l2r'],
7
- ['t2b', 'r2l'],
8
- ['b2t', 'l2r'],
9
- ['b2t', 'r2l'],
10
- ['l2r', 't2b'],
11
- ['l2r', 'b2t'],
12
- ['r2l', 't2b'],
13
- ['r2l', 'b2t'],
14
- ]
15
-
16
- describe('regular labware', () => {
17
- const regularOrdering = [
18
- ['A1', 'B1'],
19
- ['A2', 'B2'],
20
- ]
21
- const regularAnswerMap: Record<
22
- WellOrderOption,
23
- Partial<Record<WellOrderOption, string[]>>
24
- > = {
25
- t2b: {
26
- l2r: ['A1', 'B1', 'A2', 'B2'],
27
- r2l: ['A2', 'B2', 'A1', 'B1'],
28
- },
29
- b2t: {
30
- l2r: ['B1', 'A1', 'B2', 'A2'],
31
- r2l: ['B2', 'A2', 'B1', 'A1'],
32
- },
33
- l2r: {
34
- t2b: ['A1', 'A2', 'B1', 'B2'],
35
- b2t: ['B1', 'B2', 'A1', 'A2'],
36
- },
37
- r2l: {
38
- t2b: ['A2', 'A1', 'B2', 'B1'],
39
- b2t: ['B2', 'B1', 'A2', 'A1'],
40
- },
41
- }
42
- orderTuples.forEach(tuple => {
43
- it(`first ${tuple[0]} then ${tuple[1]}`, () => {
44
- expect(orderWells(regularOrdering, ...tuple)).toEqual(
45
- regularAnswerMap[tuple[0]][tuple[1]]
46
- )
47
- })
48
- })
49
- describe('irregular labware', () => {
50
- const irregularOrdering = [
51
- ['A1', 'B1'],
52
- ['A2', 'B2', 'C2'],
53
- ['A3'],
54
- ['A4', 'B4', 'C4', 'D4'],
55
- ]
56
- const irregularAnswerMap: Record<
57
- WellOrderOption,
58
- Partial<Record<WellOrderOption, string[]>>
59
- > = {
60
- t2b: {
61
- l2r: ['A1', 'B1', 'A2', 'B2', 'C2', 'A3', 'A4', 'B4', 'C4', 'D4'],
62
- r2l: ['A4', 'B4', 'C4', 'D4', 'A3', 'A2', 'B2', 'C2', 'A1', 'B1'],
63
- },
64
- b2t: {
65
- l2r: ['B1', 'A1', 'C2', 'B2', 'A2', 'A3', 'D4', 'C4', 'B4', 'A4'],
66
- r2l: ['D4', 'C4', 'B4', 'A4', 'A3', 'C2', 'B2', 'A2', 'B1', 'A1'],
67
- },
68
- l2r: {
69
- t2b: ['A1', 'A2', 'A3', 'A4', 'B1', 'B2', 'B4', 'C2', 'C4', 'D4'],
70
- b2t: ['D4', 'C2', 'C4', 'B1', 'B2', 'B4', 'A1', 'A2', 'A3', 'A4'],
71
- },
72
- r2l: {
73
- t2b: ['A4', 'A3', 'A2', 'A1', 'B4', 'B2', 'B1', 'C4', 'C2', 'D4'],
74
- b2t: ['D4', 'C4', 'C2', 'B4', 'B2', 'B1', 'A4', 'A3', 'A2', 'A1'],
75
- },
76
- }
77
-
78
- orderTuples.forEach(tuple => {
79
- it(`first ${tuple[0]} then ${tuple[1]}`, () => {
80
- expect(orderWells(irregularOrdering, ...tuple)).toEqual(
81
- irregularAnswerMap[tuple[0]][tuple[1]]
82
- )
83
- })
84
- })
85
- })
86
- })
87
- })
@@ -1,165 +0,0 @@
1
- // json protocol file validator tests
2
- import fixtureV1JsonProtocol from '../../../protocol/fixtures/1/simple.json'
3
- import fixtureV3JsonProtocol from '../../../protocol/fixtures/3/simple.json'
4
- import fixtureV4JsonProtocol from '../../../protocol/fixtures/4/simpleV4.json'
5
- import fixtureV5JsonProtocol from '../../../protocol/fixtures/5/simpleV5.json'
6
- import {
7
- fileExtensionIsPython,
8
- fileExtensionIsJson,
9
- fileExtensionIsZip,
10
- validateJsonProtocolFileContents,
11
- parseProtocolData,
12
- } from '../parseProtocolData'
13
-
14
- describe('validateJsonProtocolFileContents', () => {
15
- let handleError: jest.MockedFunction<any>
16
- // beforeAll
17
-
18
- beforeEach(() => {
19
- handleError = jest.fn()
20
- })
21
-
22
- afterEach(() => {
23
- jest.resetAllMocks()
24
- })
25
-
26
- it(`should validate schemaV3 JSON protocol`, () => {
27
- const data = validateJsonProtocolFileContents(
28
- JSON.stringify(fixtureV3JsonProtocol)
29
- )
30
- expect(data).toStrictEqual(fixtureV3JsonProtocol)
31
- })
32
-
33
- it(`should validate schemaV4 JSON protocol`, () => {
34
- const data = validateJsonProtocolFileContents(
35
- JSON.stringify(fixtureV4JsonProtocol)
36
- )
37
- expect(data).toStrictEqual(fixtureV4JsonProtocol)
38
- })
39
-
40
- it(`should validate schemaV5 JSON protocol`, () => {
41
- const data = validateJsonProtocolFileContents(
42
- JSON.stringify(fixtureV5JsonProtocol)
43
- )
44
- expect(data).toStrictEqual(fixtureV5JsonProtocol)
45
- })
46
-
47
- it('should call handleError with INVALID_FILE_TYPE if empty json', () => {
48
- validateJsonProtocolFileContents('[]', handleError)
49
- expect(handleError).toBeCalledWith('INVALID_JSON_FILE', {
50
- rawError: expect.any(Error),
51
- })
52
- })
53
-
54
- it('should call handleError with INVALID_JSON_FILE if json does not validate against schema', () => {
55
- validateJsonProtocolFileContents(
56
- JSON.stringify(fixtureV1JsonProtocol),
57
- handleError
58
- )
59
- expect(handleError).toBeCalledWith('INVALID_JSON_FILE', {
60
- schemaErrors: expect.any(Array),
61
- })
62
- })
63
-
64
- it('should call handleError with INVALID_JSON_FILE if json is not parseable', () => {
65
- const parseSpy = jest.spyOn(JSON, 'parse')
66
- parseSpy.mockImplementation(() => {
67
- throw new Error('not parseable as JSON')
68
- })
69
- validateJsonProtocolFileContents('[]', handleError)
70
- expect(handleError).toBeCalledWith('INVALID_JSON_FILE', {
71
- rawError: expect.any(Error),
72
- })
73
- parseSpy.mockRestore()
74
- })
75
- })
76
-
77
- describe('file extension validators', () => {
78
- describe('fileExtensionIsPython', () => {
79
- it(`should return true if file name ends in .py`, () => {
80
- expect(fileExtensionIsPython('foo.py')).toBe(true)
81
- })
82
- it(`should return false if file name ends in anything other than .py`, () => {
83
- expect(fileExtensionIsPython('foo.json')).toBe(false)
84
- expect(fileExtensionIsPython('foo.zip')).toBe(false)
85
- expect(fileExtensionIsPython('foo.pie')).toBe(false)
86
- })
87
- })
88
- describe('fileExtensionIsJson', () => {
89
- it(`should return true if file name ends in .json`, () => {
90
- expect(fileExtensionIsJson('foo.json')).toBe(true)
91
- })
92
- it(`should return false if file name ends in anything other than .json`, () => {
93
- expect(fileExtensionIsJson('foo.py')).toBe(false)
94
- expect(fileExtensionIsJson('foo.zip')).toBe(false)
95
- expect(fileExtensionIsJson('foo.pie')).toBe(false)
96
- })
97
- })
98
- describe('fileExtensionIsZip', () => {
99
- it(`should return true if file name ends in .zip`, () => {
100
- expect(fileExtensionIsZip('foo.zip')).toBe(true)
101
- })
102
- it(`should return false if file name ends in anything other than .zip`, () => {
103
- expect(fileExtensionIsZip('foo.py')).toBe(false)
104
- expect(fileExtensionIsZip('foo.json')).toBe(false)
105
- expect(fileExtensionIsZip('foo.pie')).toBe(false)
106
- })
107
- })
108
- describe('fileIsBinary', () => {
109
- it(`should return true if file name ends in .zip`, () => {
110
- expect(fileExtensionIsZip('foo.zip')).toBe(true)
111
- })
112
- it(`should return false if file name ends in anything other than .zip`, () => {
113
- expect(fileExtensionIsZip('foo.py')).toBe(false)
114
- expect(fileExtensionIsZip('foo.json')).toBe(false)
115
- expect(fileExtensionIsZip('foo.pie')).toBe(false)
116
- })
117
- })
118
- })
119
-
120
- describe('parseProtocolData', () => {
121
- let handleError: jest.MockedFunction<any>
122
- beforeEach(() => {
123
- handleError = jest.fn()
124
- })
125
-
126
- afterEach(() => {
127
- jest.resetAllMocks()
128
- })
129
-
130
- it(`should return null if not JSON and metadata not given`, () => {
131
- const contents = 'from math import sqrt'
132
- const pythonFile = new File([contents], 'foo.py')
133
- expect(parseProtocolData(pythonFile, contents)).toBe(null)
134
- })
135
- it(`should return metadata if not JSON and metadata is given`, () => {
136
- const contents = 'from math import sqrt'
137
- const pythonFile = new File([contents], 'foo.py')
138
- const metadata = {
139
- 'protocol-name': 'Foo Extraction',
140
- author: 'Dr. Bar Baz',
141
- } as any
142
- expect(
143
- parseProtocolData(pythonFile, contents, handleError, metadata)
144
- ).toStrictEqual({ metadata })
145
- })
146
- it(`should return JSON protocol file if valid json protocol given`, () => {
147
- const contents = JSON.stringify(fixtureV5JsonProtocol)
148
- const jsonFile = new File([contents], 'valid.json')
149
- expect(parseProtocolData(jsonFile, contents, handleError)).toStrictEqual(
150
- fixtureV5JsonProtocol
151
- )
152
- })
153
- it(`should call handleError if given JSON protocol not valid`, () => {
154
- const contents = JSON.stringify(fixtureV1JsonProtocol)
155
- const jsonFile = new File([contents], 'invalid.json')
156
- expect(parseProtocolData(jsonFile, contents, handleError)).toBe(null)
157
- expect(handleError).toHaveBeenCalled()
158
- })
159
- it(`should call handleError if given invalid file extension`, () => {
160
- const contents = JSON.stringify(fixtureV1JsonProtocol)
161
- const jsonFile = new File([contents], 'invalid.foobar')
162
- expect(parseProtocolData(jsonFile, contents, handleError)).toBe(null)
163
- expect(handleError).toHaveBeenCalledWith('INVALID_FILE_TYPE')
164
- })
165
- })