@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
@@ -1,141 +0,0 @@
1
- import Ajv from 'ajv'
2
- import labwareV2Schema from '../../labware/schemas/2.json'
3
- import protocolSchemaV1 from '../../protocol/schemas/1.json'
4
- import protocolSchemaV2 from '../../protocol/schemas/2.json'
5
- import protocolSchemaV3 from '../../protocol/schemas/3.json'
6
- import protocolSchemaV4 from '../../protocol/schemas/4.json'
7
- import protocolSchemaV5 from '../../protocol/schemas/5.json'
8
-
9
- import type { ErrorObject } from 'ajv'
10
- import type { JsonProtocolFile } from '../../protocol'
11
-
12
- export type ProtocolParseErrorKey = 'INVALID_FILE_TYPE' | 'INVALID_JSON_FILE'
13
-
14
- interface ProtocolParseErrorDetails {
15
- rawError?: string
16
- schemaErrors?: ErrorObject[] | null
17
- }
18
-
19
- export type ProtocolParseErrorHandler = (
20
- errorKey: ProtocolParseErrorKey,
21
- errorDetails?: ProtocolParseErrorDetails
22
- ) => unknown
23
-
24
- type ProtocolSchema =
25
- | typeof protocolSchemaV1
26
- | typeof protocolSchemaV2
27
- | typeof protocolSchemaV3
28
- | typeof protocolSchemaV4
29
- | typeof protocolSchemaV5
30
-
31
- const SCHEMA_BY_VERSION: { [version: string]: ProtocolSchema } = {
32
- '1': protocolSchemaV1,
33
- '2': protocolSchemaV2,
34
- '3': protocolSchemaV3,
35
- '4': protocolSchemaV4,
36
- '5': protocolSchemaV5,
37
- }
38
-
39
- export interface PythonProtocolMetadata {
40
- source?: string
41
- [key: string]: unknown
42
- }
43
-
44
- // data may be a full JSON protocol or just a metadata dict from Python
45
- export type ProtocolData =
46
- | JsonProtocolFile
47
- | { metadata: PythonProtocolMetadata }
48
-
49
- export function parseProtocolData(
50
- file: File,
51
- contents: string,
52
- handleError?: ProtocolParseErrorHandler,
53
- metadata?: PythonProtocolMetadata | null // optional Python protocol metadata
54
- ): ProtocolData | null {
55
- if (fileExtensionIsJson(file.name)) {
56
- return validateJsonProtocolFileContents(contents, handleError)
57
- } else if (fileExtensionIsPython(file.name)) {
58
- // grab Python protocol metadata, if any
59
- return metadata != null ? { metadata } : null
60
- } else if (fileExtensionIsZip(file.name)) {
61
- return null
62
- }
63
-
64
- handleError && handleError('INVALID_FILE_TYPE')
65
- return null
66
- }
67
-
68
- export function fileExtensionIsPython(filename: string): boolean {
69
- return Boolean(/\.py$/i.test(filename))
70
- }
71
- export function fileExtensionIsJson(filename: string): boolean {
72
- return Boolean(/\.json$/i.test(filename))
73
- }
74
- export function fileExtensionIsZip(filename: string): boolean {
75
- return Boolean(/\.zip$/i.test(filename))
76
- }
77
- export function fileIsBinary(file: File): boolean {
78
- // bundles are always binary files, and currently nothing else is binary
79
- return fileExtensionIsZip(file.name)
80
- }
81
-
82
- export function validateJsonProtocolFileContents(
83
- fileContents: string,
84
- handleError?: ProtocolParseErrorHandler
85
- ): JsonProtocolFile | null {
86
- try {
87
- if (typeof fileContents !== 'string') {
88
- handleError && handleError('INVALID_FILE_TYPE')
89
- return null
90
- } else {
91
- const ajv = new Ajv({ allErrors: true, jsonPointers: true })
92
- // protocol schema contains reference to v2 labware schema, so give AJV access to it
93
- ajv.addSchema(labwareV2Schema)
94
-
95
- const parsedProtocol = JSON.parse(fileContents) as any
96
- let validateAgainstSchema
97
- if ('protocol-schema' in parsedProtocol) {
98
- // 'protocol-schema' key only present in V1
99
- validateAgainstSchema = ajv.compile(protocolSchemaV1)
100
- } else {
101
- const { schemaVersion } = parsedProtocol
102
- validateAgainstSchema = ajv.compile(
103
- SCHEMA_BY_VERSION[String(schemaVersion)]
104
- )
105
- }
106
-
107
- if (!validateAgainstSchema(parsedProtocol)) {
108
- handleError &&
109
- handleError('INVALID_JSON_FILE', {
110
- schemaErrors: validateAgainstSchema.errors,
111
- })
112
- return null
113
- }
114
-
115
- return parsedProtocol
116
- }
117
- } catch (error) {
118
- handleError && handleError('INVALID_JSON_FILE', { rawError: error })
119
- return null
120
- }
121
- }
122
-
123
- export function getProtocolDesignerApplicationName(
124
- protocol: JsonProtocolFile
125
- ): string | null {
126
- if (
127
- 'designerApplication' in protocol &&
128
- protocol.designerApplication != null
129
- ) {
130
- return 'name' in protocol.designerApplication &&
131
- protocol.designerApplication.name != null
132
- ? protocol.designerApplication.name
133
- : null
134
- } else if (
135
- 'designer-application' in protocol &&
136
- protocol['designer-application']['application-name'] != null
137
- ) {
138
- return protocol['designer-application']['application-name']
139
- }
140
- return null
141
- }
@@ -1,35 +0,0 @@
1
- // utilities for working with volumes in µL
2
- import round from 'lodash/round'
3
-
4
- import type { LabwareVolumeUnits } from '../types'
5
-
6
- const SCALE_BY_UNITS = {
7
- µL: 1,
8
- mL: 1000,
9
- L: 1000000,
10
- }
11
-
12
- export function getDisplayVolume(
13
- volumeInMicroliters: number,
14
- displayUnits: LabwareVolumeUnits = 'µL',
15
- digits?: number
16
- ): string {
17
- const volume = volumeInMicroliters / SCALE_BY_UNITS[displayUnits]
18
-
19
- return `${typeof digits === 'number' ? round(volume, digits) : volume}`
20
- }
21
-
22
- export function getAsciiVolumeUnits(displayUnits: LabwareVolumeUnits): string {
23
- if (displayUnits === 'µL') return 'uL'
24
-
25
- return displayUnits
26
- }
27
-
28
- export function ensureVolumeUnits(
29
- maybeUnits: string | null | undefined
30
- ): LabwareVolumeUnits {
31
- if (maybeUnits === 'mL' || maybeUnits === 'ml') return 'mL'
32
- if (maybeUnits === 'L' || maybeUnits === 'l') return 'L'
33
-
34
- return 'µL'
35
- }
@@ -1,6 +0,0 @@
1
- import type { WellDefinition } from '../types'
2
-
3
- /** Well is either rect or circle. Depends on whether `diameter` exists */
4
- export function wellIsRect(wellDef: WellDefinition): boolean {
5
- return !(typeof wellDef.diameter === 'number')
6
- }
@@ -1,155 +0,0 @@
1
- // A "well set" is an array of wells corresponding to each tip of an 8 channel pipette.
2
- // Eg ['A1', 'C1', 'E1', 'G1', 'I1', 'K1', 'M1', 'O1'] is a well set in a 384 plate.
3
- //
4
- // A trough-like well that encompasses all 8 tips at once has a well set
5
- // ['A1', 'A1', 'A1', 'A1', 'A1', 'A1', 'A1', 'A1']
6
- //
7
- // Well sets are determined by geometry.
8
- //
9
- // Labware with multiple positions for an 8-channel pipette have multiple well sets.
10
- // For example, a 96 plate has 12 well sets, one for each column.
11
- // A 384 plate has 48 well sets, 2 for each column b/c it has staggered columns.
12
- //
13
- // If a labware has no possible well sets, then it is not compatible with multi-channel pipettes.
14
- import uniq from 'lodash/uniq'
15
-
16
- import { getWellNamePerMultiTip } from './getWellNamePerMultiTip'
17
- import { get96Channel384WellPlateWells, getLabwareDefURI, orderWells } from '.'
18
- import type { LabwareDefinition2, PipetteNameSpecs } from '../types'
19
-
20
- type WellSetByPrimaryWell = string[][]
21
-
22
- // Compute all well sets for a labware def (non-memoized)
23
- function _getAllWellSetsForLabware(
24
- labwareDef: LabwareDefinition2
25
- ): WellSetByPrimaryWell {
26
- const allWells: string[] = Object.keys(labwareDef.wells)
27
-
28
- return allWells.reduce(
29
- (acc: WellSetByPrimaryWell, well: string): WellSetByPrimaryWell => {
30
- const wellSet = getWellNamePerMultiTip(labwareDef, well, 8)
31
- if (wellSet === null) {
32
- return acc
33
- } else {
34
- return [...acc, wellSet]
35
- }
36
- },
37
- []
38
- )
39
- }
40
-
41
- // creates memoized getAllWellSetsForLabware + getWellSetForMultichannel fns.
42
- export interface WellSetHelpers {
43
- getAllWellSetsForLabware: (
44
- labwareDef: LabwareDefinition2
45
- ) => WellSetByPrimaryWell
46
-
47
- getWellSetForMultichannel: (
48
- labwareDef: LabwareDefinition2,
49
- well: string,
50
- channels: 8 | 96
51
- ) => string[] | null | undefined
52
-
53
- canPipetteUseLabware: (
54
- pipetteSpec: PipetteNameSpecs,
55
- labwareDef?: LabwareDefinition2,
56
- trashName?: string
57
- ) => boolean
58
- }
59
-
60
- export const makeWellSetHelpers = (): WellSetHelpers => {
61
- const cache: Partial<{
62
- [labwareDefURI: string]: {
63
- labwareDef: LabwareDefinition2
64
- wellSetByPrimaryWell: WellSetByPrimaryWell
65
- } | null
66
- }> = {}
67
-
68
- const getAllWellSetsForLabware = (
69
- labwareDef: LabwareDefinition2
70
- ): WellSetByPrimaryWell => {
71
- const labwareDefURI = getLabwareDefURI(labwareDef)
72
- const c = cache[labwareDefURI]
73
-
74
- // use cached version only if labwareDef is shallowly equal, in case
75
- // custom labware defs are changed without giving them a new URI
76
- if (c && c.labwareDef === labwareDef) {
77
- return c.wellSetByPrimaryWell
78
- }
79
-
80
- const wellSetByPrimaryWell = _getAllWellSetsForLabware(labwareDef)
81
-
82
- cache[labwareDefURI] = {
83
- labwareDef,
84
- wellSetByPrimaryWell,
85
- }
86
- return wellSetByPrimaryWell
87
- }
88
-
89
- const getWellSetForMultichannel = (
90
- labwareDef: LabwareDefinition2,
91
- well: string,
92
- channels: 8 | 96
93
- ): string[] | null | undefined => {
94
- /** Given a well for a labware, returns the well set it belongs to (or null)
95
- * for 8-channel access.
96
- * Ie: C2 for 96-flat => ['A2', 'B2', 'C2', ... 'H2']
97
- * Or A1 for trough => ['A1', 'A1', 'A1', ...]
98
- **/
99
- const allWellSetsFor8Channel = getAllWellSetsForLabware(labwareDef)
100
- /** getting all wells from the plate and turning into 1D array for 96-channel
101
- */
102
- const orderedWellsFor96Channel = orderWells(
103
- labwareDef.ordering,
104
- 't2b',
105
- 'l2r'
106
- )
107
-
108
- let ninetySixChannelWells = orderedWellsFor96Channel
109
- /** special casing 384 well plates to be every other well
110
- * both on the x and y ases.
111
- */
112
- if (orderedWellsFor96Channel.length === 384) {
113
- ninetySixChannelWells = get96Channel384WellPlateWells(
114
- orderedWellsFor96Channel,
115
- well
116
- )
117
- }
118
- return channels === 8
119
- ? allWellSetsFor8Channel.find((wellSet: string[]) =>
120
- wellSet.includes(well)
121
- )
122
- : ninetySixChannelWells
123
- }
124
-
125
- const canPipetteUseLabware = (
126
- pipetteSpec: PipetteNameSpecs,
127
- labwareDef?: LabwareDefinition2,
128
- trashName?: string
129
- ): boolean => {
130
- if (pipetteSpec.channels === 1 || trashName != null) {
131
- // assume all labware can be used by single-channel
132
- return true
133
- }
134
- if (labwareDef != null) {
135
- const allWellSets = getAllWellSetsForLabware(labwareDef)
136
- return allWellSets.some(wellSet => {
137
- const uniqueWells = uniq(wellSet)
138
- // if all wells are non-null, and there are either 1 (reservoir-like)
139
- // or 8 (well plate-like) unique wells in the set,
140
- // then assume both 8 and 96 channel pipettes will work
141
- return (
142
- uniqueWells.every(well => well != null) &&
143
- [1, 8].includes(uniqueWells.length)
144
- )
145
- })
146
- } else {
147
- return false
148
- }
149
- }
150
- return {
151
- getAllWellSetsForLabware,
152
- getWellSetForMultichannel,
153
- canPipetteUseLabware,
154
- }
155
- }
package/js/index.ts DELETED
@@ -1,14 +0,0 @@
1
- export * from './constants'
2
- export * from './getLabware'
3
- export * from './helpers'
4
- export * from './pipettes'
5
- export * from './types'
6
- export * from './labwareTools'
7
- export * from './modules'
8
- export * from './fixtures'
9
- export * from './gripper'
10
- export * from '../protocol'
11
- export * from '../deck'
12
- export * from './titleCase'
13
- export * from './errors'
14
- export * from './fixtures'
@@ -1,3 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`test createIrregularLabware function failing to validate against labware schema throws w/o "strict" 1`] = `"Generated labware failed to validate, please check your inputs"`;
@@ -1,3 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`createLabware failing to validate against labware schema throws w/o "strict" 1`] = `"Generated labware failed to validate, please check your inputs"`;
@@ -1,111 +0,0 @@
1
- import { createDefaultDisplayName } from '..'
2
-
3
- import type { RegularNameProps } from '..'
4
-
5
- interface TestCase {
6
- testName: string
7
- args: RegularNameProps
8
- expected: string
9
- }
10
-
11
- describe('createDefaultDisplayName', () => {
12
- const testCases: TestCase[] = [
13
- {
14
- testName: 'handle the minimal case',
15
- args: {
16
- displayCategory: 'wellPlate',
17
- displayVolumeUnits: 'µL',
18
- gridRows: 2,
19
- gridColumns: 3,
20
- totalLiquidVolume: 123,
21
- },
22
- expected: 'Generic 6 Well Plate 123 µL',
23
- },
24
- {
25
- testName: 'handle a decimal in volume',
26
- args: {
27
- displayCategory: 'wellPlate',
28
- displayVolumeUnits: 'µL',
29
- gridRows: 2,
30
- gridColumns: 3,
31
- totalLiquidVolume: 12.3,
32
- },
33
- expected: 'Generic 6 Well Plate 12.3 µL',
34
- },
35
- {
36
- testName: 'calculate wells = rows x cols',
37
- args: {
38
- displayCategory: 'wellPlate',
39
- displayVolumeUnits: 'µL',
40
- gridRows: 8,
41
- gridColumns: 10,
42
- totalLiquidVolume: 123,
43
- },
44
- expected: 'Generic 80 Well Plate 123 µL',
45
- },
46
- {
47
- testName: 'handle tube rack (example of a different displayCategory)',
48
- args: {
49
- displayCategory: 'tubeRack',
50
- displayVolumeUnits: 'µL',
51
- gridRows: 2,
52
- gridColumns: 3,
53
- totalLiquidVolume: 123,
54
- },
55
- expected: 'Generic 6 Tube Rack 123 µL',
56
- },
57
- {
58
- testName: 'append loadNamePostfix',
59
- args: {
60
- displayCategory: 'wellPlate',
61
- displayVolumeUnits: 'µL',
62
- gridRows: 2,
63
- gridColumns: 3,
64
- totalLiquidVolume: 123,
65
- loadNamePostfix: ['spam ', ' blah', 'PCR'],
66
- },
67
- expected: 'Generic 6 Well Plate 123 µL Spam Blah PCR',
68
- },
69
- {
70
- testName: 'support brand name when specified (ignore extra whitespace)',
71
- args: {
72
- displayCategory: 'wellPlate',
73
- displayVolumeUnits: 'µL',
74
- gridRows: 2,
75
- gridColumns: 3,
76
- totalLiquidVolume: 123,
77
- brandName: ' cool brand ',
78
- },
79
- expected: 'Cool Brand 6 Well Plate 123 µL',
80
- },
81
- {
82
- testName: 'support brand name when specified (capitalization)',
83
- args: {
84
- displayCategory: 'wellPlate',
85
- displayVolumeUnits: 'µL',
86
- gridRows: 2,
87
- gridColumns: 3,
88
- totalLiquidVolume: 123,
89
- brandName: ' BIO tech',
90
- },
91
- expected: 'BIO Tech 6 Well Plate 123 µL',
92
- },
93
- {
94
- testName: 'support mL when specified (volume number always in µL!)',
95
- args: {
96
- displayCategory: 'wellPlate',
97
- displayVolumeUnits: 'mL',
98
- gridRows: 2,
99
- gridColumns: 3,
100
- totalLiquidVolume: 123,
101
- },
102
- expected: 'Generic 6 Well Plate 0.123 mL',
103
- },
104
- ]
105
-
106
- testCases.forEach(({ testName, args, expected }) => {
107
- it(`should ${testName}`, () => {
108
- expect(createDefaultDisplayName(args)).toEqual(expected)
109
- })
110
- })
111
- })
@@ -1,226 +0,0 @@
1
- import omit from 'lodash/omit'
2
- import range from 'lodash/range'
3
-
4
- import { splitWellsOnColumn, sortWells } from '../../helpers/index'
5
- import fixture_irregular_example_1 from '../../../labware/fixtures/2/fixture_irregular_example_1.json'
6
-
7
- import {
8
- createIrregularLabware,
9
- _irregularWellName,
10
- _generateIrregularLoadName,
11
- _calculateWellCoord,
12
- } from '..'
13
-
14
- import type { LabwareDefinition2, LabwareWellProperties } from '../../types'
15
- import type { IrregularLabwareProps } from '..'
16
-
17
- // NOTE: loadName needs to be replaced here b/c fixture has a non-default loadName
18
- const exampleLabware1 = {
19
- ...fixture_irregular_example_1,
20
- parameters: {
21
- ...fixture_irregular_example_1.parameters,
22
- loadName: 'generic_55_tuberack_50x3ml_5x10ml',
23
- },
24
- } as LabwareDefinition2
25
-
26
- describe('test helper functions', () => {
27
- it('Well name generated correctly', () => {
28
- const grid = { row: 2, column: 2 }
29
-
30
- const gridStart = [
31
- { rowStart: 'A', colStart: '1', rowStride: 1, colStride: 2 },
32
- { rowStart: 'B', colStart: '1', rowStride: 3, colStride: 1 },
33
- ]
34
- const expected1 = ['A1', 'B1', 'A3', 'B3']
35
- const expected2 = ['B1', 'E1', 'B2', 'E2']
36
-
37
- range(grid.column).forEach(colIdx => {
38
- range(grid.row).forEach(rowIdx => {
39
- const idx = colIdx * grid.row + rowIdx
40
-
41
- const wellName1 = _irregularWellName(rowIdx, colIdx, gridStart[0])
42
-
43
- expect(expected1[idx]).toEqual(wellName1)
44
-
45
- const wellName2 = _irregularWellName(rowIdx, colIdx, gridStart[1])
46
-
47
- expect(expected2[idx]).toEqual(wellName2)
48
- })
49
- })
50
- })
51
-
52
- it('XYZ generates correctly for each grid', () => {
53
- const grid = { row: 1, column: 5 }
54
- const offset = { x: 1, y: 0.5, z: 55.5 }
55
- const spacing = [
56
- { row: 10, column: 10 },
57
- { row: 5, column: 14 },
58
- ]
59
- const well = [
60
- omit(exampleLabware1.wells.A1, ['x', 'y', 'z']),
61
- omit(exampleLabware1.wells.B1, ['x', 'y', 'z']),
62
- ] as LabwareWellProperties[]
63
-
64
- const expectedX1 = [1, 11, 21, 31, 41]
65
- const expectedY1 = [0.5]
66
- const expectedX2 = [1, 15, 29, 43, 57]
67
- const expectedY2 = [0.5]
68
-
69
- range(grid.column).forEach(colIdx => {
70
- range(grid.row).forEach(rowIdx => {
71
- const well1 = _calculateWellCoord(
72
- rowIdx,
73
- colIdx,
74
- spacing[0],
75
- offset,
76
- well[0]
77
- )
78
-
79
- expect(well1.x).toBeCloseTo(expectedX1[colIdx], 2)
80
- expect(well1.y).toBeCloseTo(expectedY1[rowIdx], 2)
81
- expect(well1.z).toBeCloseTo(offset.z - well[0].depth, 2)
82
-
83
- const well2 = _calculateWellCoord(
84
- rowIdx,
85
- colIdx,
86
- spacing[1],
87
- offset,
88
- well[1]
89
- )
90
-
91
- expect(well2.x).toBeCloseTo(expectedX2[colIdx], 2)
92
- expect(well2.y).toBeCloseTo(expectedY2[rowIdx], 2)
93
- expect(well2.z).toBeCloseTo(offset.z - well[1].depth, 2)
94
- })
95
- })
96
- })
97
- })
98
-
99
- describe('test createIrregularLabware function', () => {
100
- let labware1: LabwareDefinition2
101
- let labware1Args: IrregularLabwareProps
102
-
103
- beforeEach(() => {
104
- labware1Args = {
105
- namespace: 'fixture',
106
- metadata: {
107
- displayName: 'Fake Irregular Container',
108
- displayCategory: 'tubeRack',
109
- displayVolumeUnits: 'mL',
110
- tags: ['fake', 'opentrons'],
111
- },
112
- parameters: {
113
- format: 'irregular',
114
- isTiprack: false,
115
- isMagneticModuleCompatible: false,
116
- },
117
- dimensions: {
118
- xDimension: 127.76,
119
- yDimension: 85.48,
120
- zDimension: 64.48,
121
- },
122
- well: [
123
- {
124
- depth: 10.54,
125
- shape: 'circular',
126
- diameter: 10,
127
- totalLiquidVolume: 3000,
128
- },
129
- {
130
- depth: 20.54,
131
- shape: 'circular',
132
- diameter: 15,
133
- totalLiquidVolume: 10000,
134
- },
135
- ],
136
- offset: [
137
- { x: 10, y: 10, z: 69.48 },
138
- { x: 15, y: 15, z: 69.48 },
139
- ],
140
- grid: [
141
- { row: 5, column: 10 },
142
- { row: 1, column: 5 },
143
- ],
144
- spacing: [
145
- { row: 5, column: 10 },
146
- { row: 5, column: 10 },
147
- ],
148
- gridStart: [
149
- { rowStart: 'A', colStart: '1', rowStride: 2, colStride: 1 },
150
- { rowStart: 'B', colStart: '1', rowStride: 1, colStride: 1 },
151
- ],
152
- }
153
- labware1 = createIrregularLabware(labware1Args)
154
- })
155
-
156
- it('irregular ordering generates as expected', () => {
157
- const keyList = Object.keys(labware1.wells)
158
- const generatedOrdering = splitWellsOnColumn(keyList.sort(sortWells))
159
- expect(labware1.ordering).toEqual(generatedOrdering)
160
- })
161
-
162
- it('check labware matches fixture', () => {
163
- expect(labware1).toEqual(exampleLabware1)
164
- })
165
-
166
- it('labware loadName generated correctly for multi-grid labware', () => {
167
- const loadName = _generateIrregularLoadName({
168
- grid: [
169
- { row: 3, column: 2 },
170
- { row: 1, column: 4 },
171
- ],
172
- well: [
173
- {
174
- depth: 20,
175
- shape: 'circular',
176
- totalLiquidVolume: 400,
177
- } as LabwareWellProperties,
178
- {
179
- depth: 110,
180
- shape: 'circular',
181
- totalLiquidVolume: 2000,
182
- } as LabwareWellProperties,
183
- ],
184
- totalWellCount: 10,
185
- units: 'µL',
186
- displayCategory: 'wellPlate',
187
- brand: 'some brand',
188
- })
189
-
190
- expect(loadName).toEqual('somebrand_10_wellplate_6x400ul_4x2000ul')
191
- })
192
-
193
- it('labware loadName generated correctly for multi-grid labware in other units', () => {
194
- const loadName = _generateIrregularLoadName({
195
- grid: [{ row: 3, column: 2 }],
196
- well: [
197
- {
198
- depth: 20,
199
- shape: 'circular',
200
- totalLiquidVolume: 4000,
201
- } as LabwareWellProperties,
202
- ],
203
- totalWellCount: 6,
204
- units: 'mL',
205
- displayCategory: 'wellPlate',
206
- brand: 'some brand',
207
- })
208
-
209
- expect(loadName).toEqual('somebrand_6_wellplate_6x4ml')
210
- })
211
-
212
- it('failing to validate against labware schema throws w/o "strict"', () => {
213
- const args = {
214
- ...labware1Args,
215
- // negative y offset should fail schema validation by making well `y` negative
216
- offset: [
217
- { x: 10, y: -9999, z: 69.48 },
218
- { x: 15, y: -9999, z: 69.48 },
219
- ],
220
- }
221
- expect(() => createIrregularLabware(args)).toThrowErrorMatchingSnapshot()
222
- expect(() =>
223
- createIrregularLabware({ ...args, strict: false })
224
- ).not.toThrow()
225
- })
226
- })