@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.
- package/package.json +1 -1
- package/js/__tests__/__snapshots__/pipettes.test.ts.snap +0 -5969
- package/js/__tests__/deckSchemas.test.ts +0 -87
- package/js/__tests__/errors.test.js +0 -21
- package/js/__tests__/getAreSlotsAdjacent.test.ts +0 -128
- package/js/__tests__/getWellNamePerMultiTip.test.ts +0 -162
- package/js/__tests__/labwareDefQuirks.test.ts +0 -37
- package/js/__tests__/labwareDefSchemaV1.test.ts +0 -82
- package/js/__tests__/labwareDefSchemaV2.test.ts +0 -298
- package/js/__tests__/moduleAccessors.test.ts +0 -50
- package/js/__tests__/moduleSpecsSchema.test.ts +0 -77
- package/js/__tests__/pipetteSchemaV2.test.ts +0 -107
- package/js/__tests__/pipetteSpecSchemas.test.ts +0 -48
- package/js/__tests__/pipettes.test.ts +0 -58
- package/js/__tests__/protocolSchemaV4.test.ts +0 -137
- package/js/__tests__/protocolSchemaV5.test.ts +0 -137
- package/js/__tests__/protocolSchemaV6.test.ts +0 -132
- package/js/__tests__/protocolSchemaV7.test.ts +0 -64
- package/js/__tests__/protocolValidation.test.ts +0 -83
- package/js/__tests__/sortWells.test.ts +0 -40
- package/js/__tests__/splitWellsOnColumn.test.ts +0 -21
- package/js/__tests__/validateErrors.test.js +0 -34
- package/js/constants.ts +0 -338
- package/js/cypressUtils.ts +0 -35
- package/js/errors.ts +0 -33
- package/js/fixtures.ts +0 -161
- package/js/getLabware.ts +0 -154
- package/js/gripper.ts +0 -29
- package/js/helpers/__tests__/getAdapterName.test.ts +0 -31
- package/js/helpers/__tests__/getDeckDefFromLoadedLabware.test.ts +0 -12
- package/js/helpers/__tests__/getVectorDifference.test.ts +0 -25
- package/js/helpers/__tests__/getVectorSum.test.ts +0 -21
- package/js/helpers/__tests__/labwareInference.test.ts +0 -84
- package/js/helpers/__tests__/orderWells.test.ts +0 -87
- package/js/helpers/__tests__/parseProtocolData.test.ts +0 -165
- package/js/helpers/__tests__/volume.test.ts +0 -108
- package/js/helpers/__tests__/wellSets.test.ts +0 -352
- package/js/helpers/get96Channel384WellPlateWells.ts +0 -44
- package/js/helpers/getAddressableAreasInProtocol.ts +0 -59
- package/js/helpers/getLoadedLabwareDefinitionsByUri.ts +0 -30
- package/js/helpers/getModuleVizDims.ts +0 -118
- package/js/helpers/getOccludedSlotCountForModule.ts +0 -13
- package/js/helpers/getVectorDifference.ts +0 -12
- package/js/helpers/getVectorSum.ts +0 -12
- package/js/helpers/getWellNamePerMultiTip.ts +0 -86
- package/js/helpers/getWellTotalVolume.ts +0 -16
- package/js/helpers/index.ts +0 -347
- package/js/helpers/labwareInference.ts +0 -92
- package/js/helpers/orderWells.ts +0 -69
- package/js/helpers/parseProtocolData.ts +0 -141
- package/js/helpers/volume.ts +0 -35
- package/js/helpers/wellIsRect.ts +0 -6
- package/js/helpers/wellSets.ts +0 -155
- package/js/index.ts +0 -14
- package/js/labwareTools/__tests__/__snapshots__/createIrregularLabware.test.ts.snap +0 -3
- package/js/labwareTools/__tests__/__snapshots__/createLabware.test.ts.snap +0 -3
- package/js/labwareTools/__tests__/createDefaultDisplayName.test.ts +0 -111
- package/js/labwareTools/__tests__/createIrregularLabware.test.ts +0 -226
- package/js/labwareTools/__tests__/createLabware.test.ts +0 -147
- package/js/labwareTools/index.ts +0 -452
- package/js/modules.ts +0 -97
- package/js/pipettes.ts +0 -89
- package/js/protocols.ts +0 -290
- package/js/schema.ts +0 -80
- package/js/scripts/generateDeckLayersFromSVG.js +0 -46
- package/js/titleCase.ts +0 -30
- package/js/types.ts +0 -600
- package/python/.coveragerc +0 -4
- package/python/.flake8 +0 -32
- package/python/Config.in +0 -10
- package/python/Makefile +0 -134
- package/python/Pipfile +0 -28
- package/python/Pipfile.lock +0 -645
- package/python/buildroot.mk +0 -30
- package/python/mypy.ini +0 -41
- package/python/opentrons_shared_data/__init__.py +0 -17
- package/python/opentrons_shared_data/_version.py +0 -20
- package/python/opentrons_shared_data/command/__init__.py +0 -52
- package/python/opentrons_shared_data/deck/__init__.py +0 -96
- package/python/opentrons_shared_data/deck/dev_types.py +0 -180
- package/python/opentrons_shared_data/errors/__init__.py +0 -30
- package/python/opentrons_shared_data/errors/categories.py +0 -60
- package/python/opentrons_shared_data/errors/codes.py +0 -108
- package/python/opentrons_shared_data/errors/exceptions.py +0 -915
- package/python/opentrons_shared_data/gripper/__init__.py +0 -63
- package/python/opentrons_shared_data/gripper/constants.py +0 -6
- package/python/opentrons_shared_data/gripper/gripper_definition.py +0 -101
- package/python/opentrons_shared_data/labware/__init__.py +0 -22
- package/python/opentrons_shared_data/labware/constants.py +0 -7
- package/python/opentrons_shared_data/labware/dev_types.py +0 -140
- package/python/opentrons_shared_data/labware/labware_definition.py +0 -328
- package/python/opentrons_shared_data/load.py +0 -57
- package/python/opentrons_shared_data/module/__init__.py +0 -74
- package/python/opentrons_shared_data/module/dev_types.py +0 -141
- package/python/opentrons_shared_data/pipette/__init__.py +0 -107
- package/python/opentrons_shared_data/pipette/dev_types.py +0 -177
- package/python/opentrons_shared_data/pipette/file_operation_helpers.py +0 -37
- package/python/opentrons_shared_data/pipette/load_data.py +0 -261
- package/python/opentrons_shared_data/pipette/model_constants.py +0 -123
- package/python/opentrons_shared_data/pipette/mutable_configurations.py +0 -431
- package/python/opentrons_shared_data/pipette/pipette_definition.py +0 -503
- package/python/opentrons_shared_data/pipette/pipette_load_name_conversions.py +0 -240
- package/python/opentrons_shared_data/pipette/scripts/__init__.py +0 -0
- package/python/opentrons_shared_data/pipette/scripts/build_json_script.py +0 -469
- package/python/opentrons_shared_data/pipette/scripts/update_configuration_files.py +0 -450
- package/python/opentrons_shared_data/pipette/types.py +0 -193
- package/python/opentrons_shared_data/protocol/__init__.py +0 -13
- package/python/opentrons_shared_data/protocol/constants.py +0 -98
- package/python/opentrons_shared_data/protocol/dev_types.py +0 -436
- package/python/opentrons_shared_data/protocol/models/__init__.py +0 -48
- package/python/opentrons_shared_data/protocol/models/protocol_schema_v6.py +0 -145
- package/python/opentrons_shared_data/protocol/models/protocol_schema_v7.py +0 -95
- package/python/opentrons_shared_data/protocol/models/protocol_schema_v8.py +0 -110
- package/python/opentrons_shared_data/protocol/models/shared_models.py +0 -111
- package/python/opentrons_shared_data/py.typed +0 -0
- package/python/opentrons_shared_data/robot/__init__.py +0 -33
- package/python/opentrons_shared_data/robot/dev_types.py +0 -37
- package/python/pytest.ini +0 -2
- package/python/setup.cfg +0 -5
- package/python/setup.py +0 -179
- package/python/tests/__init__.py +0 -1
- package/python/tests/conftest.py +0 -0
- package/python/tests/deck/__init__.py +0 -0
- package/python/tests/deck/test_list_names.py +0 -12
- package/python/tests/deck/test_position.py +0 -113
- package/python/tests/deck/test_typechecks.py +0 -28
- package/python/tests/errors/__init__.py +0 -1
- package/python/tests/errors/test_error_completeness.py +0 -19
- package/python/tests/errors/test_exceptions.py +0 -74
- package/python/tests/gripper/__init__.py +0 -0
- package/python/tests/gripper/test_definition.py +0 -30
- package/python/tests/gripper/test_load.py +0 -16
- package/python/tests/labware/__init__.py +0 -13
- package/python/tests/labware/test_typechecks.py +0 -21
- package/python/tests/module/__init__.py +0 -20
- package/python/tests/module/test_load.py +0 -49
- package/python/tests/module/test_typechecks.py +0 -34
- package/python/tests/pipette/__init__.py +0 -0
- package/python/tests/pipette/test_load_data.py +0 -103
- package/python/tests/pipette/test_mutable_configurations.py +0 -266
- package/python/tests/pipette/test_pipette_definition.py +0 -183
- package/python/tests/pipette/test_pipette_load_name_conversions.py +0 -222
- package/python/tests/pipette/test_typechecks.py +0 -50
- package/python/tests/pipette/test_validate_schema.py +0 -37
- package/python/tests/protocol/__init__.py +0 -15
- package/python/tests/protocol/test_protocol_schema_v6.py +0 -107
- package/python/tests/protocol/test_protocol_schema_v7.py +0 -34
- package/python/tests/protocol/test_protocol_schema_v8.py +0 -20
- package/python/tests/protocol/test_typechecks.py +0 -36
- package/python/tests/robot/__init__.py +0 -0
- 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
|
-
})
|