@opentrons/shared-data 0.0.1-alpha.20 → 0.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/Makefile +1 -1
  2. package/lib/opentrons-shared-data.js +1 -1
  3. package/lib/opentrons-shared-data.js.map +1 -1
  4. package/package.json +1 -1
  5. package/js/__tests__/__snapshots__/pipettes.test.ts.snap +0 -5969
  6. package/js/__tests__/deckSchemas.test.ts +0 -87
  7. package/js/__tests__/errors.test.js +0 -21
  8. package/js/__tests__/getAreSlotsAdjacent.test.ts +0 -128
  9. package/js/__tests__/getWellNamePerMultiTip.test.ts +0 -162
  10. package/js/__tests__/labwareDefQuirks.test.ts +0 -37
  11. package/js/__tests__/labwareDefSchemaV1.test.ts +0 -82
  12. package/js/__tests__/labwareDefSchemaV2.test.ts +0 -298
  13. package/js/__tests__/moduleAccessors.test.ts +0 -50
  14. package/js/__tests__/moduleSpecsSchema.test.ts +0 -77
  15. package/js/__tests__/pipetteSchemaV2.test.ts +0 -107
  16. package/js/__tests__/pipetteSpecSchemas.test.ts +0 -48
  17. package/js/__tests__/pipettes.test.ts +0 -58
  18. package/js/__tests__/protocolSchemaV4.test.ts +0 -137
  19. package/js/__tests__/protocolSchemaV5.test.ts +0 -137
  20. package/js/__tests__/protocolSchemaV6.test.ts +0 -132
  21. package/js/__tests__/protocolSchemaV7.test.ts +0 -64
  22. package/js/__tests__/protocolValidation.test.ts +0 -83
  23. package/js/__tests__/sortWells.test.ts +0 -40
  24. package/js/__tests__/splitWellsOnColumn.test.ts +0 -21
  25. package/js/__tests__/validateErrors.test.js +0 -34
  26. package/js/constants.ts +0 -338
  27. package/js/cypressUtils.ts +0 -35
  28. package/js/errors.ts +0 -33
  29. package/js/fixtures.ts +0 -161
  30. package/js/getLabware.ts +0 -154
  31. package/js/gripper.ts +0 -29
  32. package/js/helpers/__tests__/getAdapterName.test.ts +0 -31
  33. package/js/helpers/__tests__/getDeckDefFromLoadedLabware.test.ts +0 -12
  34. package/js/helpers/__tests__/getVectorDifference.test.ts +0 -25
  35. package/js/helpers/__tests__/getVectorSum.test.ts +0 -21
  36. package/js/helpers/__tests__/labwareInference.test.ts +0 -84
  37. package/js/helpers/__tests__/orderWells.test.ts +0 -87
  38. package/js/helpers/__tests__/parseProtocolData.test.ts +0 -165
  39. package/js/helpers/__tests__/volume.test.ts +0 -108
  40. package/js/helpers/__tests__/wellSets.test.ts +0 -352
  41. package/js/helpers/get96Channel384WellPlateWells.ts +0 -44
  42. package/js/helpers/getAddressableAreasInProtocol.ts +0 -59
  43. package/js/helpers/getLoadedLabwareDefinitionsByUri.ts +0 -30
  44. package/js/helpers/getModuleVizDims.ts +0 -118
  45. package/js/helpers/getOccludedSlotCountForModule.ts +0 -13
  46. package/js/helpers/getVectorDifference.ts +0 -12
  47. package/js/helpers/getVectorSum.ts +0 -12
  48. package/js/helpers/getWellNamePerMultiTip.ts +0 -86
  49. package/js/helpers/getWellTotalVolume.ts +0 -16
  50. package/js/helpers/index.ts +0 -347
  51. package/js/helpers/labwareInference.ts +0 -92
  52. package/js/helpers/orderWells.ts +0 -69
  53. package/js/helpers/parseProtocolData.ts +0 -141
  54. package/js/helpers/volume.ts +0 -35
  55. package/js/helpers/wellIsRect.ts +0 -6
  56. package/js/helpers/wellSets.ts +0 -155
  57. package/js/index.ts +0 -14
  58. package/js/labwareTools/__tests__/__snapshots__/createIrregularLabware.test.ts.snap +0 -3
  59. package/js/labwareTools/__tests__/__snapshots__/createLabware.test.ts.snap +0 -3
  60. package/js/labwareTools/__tests__/createDefaultDisplayName.test.ts +0 -111
  61. package/js/labwareTools/__tests__/createIrregularLabware.test.ts +0 -226
  62. package/js/labwareTools/__tests__/createLabware.test.ts +0 -147
  63. package/js/labwareTools/index.ts +0 -452
  64. package/js/modules.ts +0 -97
  65. package/js/pipettes.ts +0 -89
  66. package/js/protocols.ts +0 -290
  67. package/js/schema.ts +0 -80
  68. package/js/scripts/generateDeckLayersFromSVG.js +0 -46
  69. package/js/titleCase.ts +0 -30
  70. package/js/types.ts +0 -600
  71. package/python/.coveragerc +0 -4
  72. package/python/.flake8 +0 -32
  73. package/python/Config.in +0 -10
  74. package/python/Makefile +0 -134
  75. package/python/Pipfile +0 -28
  76. package/python/Pipfile.lock +0 -645
  77. package/python/buildroot.mk +0 -30
  78. package/python/mypy.ini +0 -41
  79. package/python/opentrons_shared_data/__init__.py +0 -17
  80. package/python/opentrons_shared_data/_version.py +0 -20
  81. package/python/opentrons_shared_data/command/__init__.py +0 -52
  82. package/python/opentrons_shared_data/deck/__init__.py +0 -96
  83. package/python/opentrons_shared_data/deck/dev_types.py +0 -180
  84. package/python/opentrons_shared_data/errors/__init__.py +0 -30
  85. package/python/opentrons_shared_data/errors/categories.py +0 -60
  86. package/python/opentrons_shared_data/errors/codes.py +0 -108
  87. package/python/opentrons_shared_data/errors/exceptions.py +0 -915
  88. package/python/opentrons_shared_data/gripper/__init__.py +0 -63
  89. package/python/opentrons_shared_data/gripper/constants.py +0 -6
  90. package/python/opentrons_shared_data/gripper/gripper_definition.py +0 -101
  91. package/python/opentrons_shared_data/labware/__init__.py +0 -22
  92. package/python/opentrons_shared_data/labware/constants.py +0 -7
  93. package/python/opentrons_shared_data/labware/dev_types.py +0 -140
  94. package/python/opentrons_shared_data/labware/labware_definition.py +0 -328
  95. package/python/opentrons_shared_data/load.py +0 -57
  96. package/python/opentrons_shared_data/module/__init__.py +0 -74
  97. package/python/opentrons_shared_data/module/dev_types.py +0 -141
  98. package/python/opentrons_shared_data/pipette/__init__.py +0 -107
  99. package/python/opentrons_shared_data/pipette/dev_types.py +0 -177
  100. package/python/opentrons_shared_data/pipette/file_operation_helpers.py +0 -37
  101. package/python/opentrons_shared_data/pipette/load_data.py +0 -261
  102. package/python/opentrons_shared_data/pipette/model_constants.py +0 -123
  103. package/python/opentrons_shared_data/pipette/mutable_configurations.py +0 -431
  104. package/python/opentrons_shared_data/pipette/pipette_definition.py +0 -503
  105. package/python/opentrons_shared_data/pipette/pipette_load_name_conversions.py +0 -240
  106. package/python/opentrons_shared_data/pipette/scripts/__init__.py +0 -0
  107. package/python/opentrons_shared_data/pipette/scripts/build_json_script.py +0 -469
  108. package/python/opentrons_shared_data/pipette/scripts/update_configuration_files.py +0 -450
  109. package/python/opentrons_shared_data/pipette/types.py +0 -193
  110. package/python/opentrons_shared_data/protocol/__init__.py +0 -13
  111. package/python/opentrons_shared_data/protocol/constants.py +0 -98
  112. package/python/opentrons_shared_data/protocol/dev_types.py +0 -436
  113. package/python/opentrons_shared_data/protocol/models/__init__.py +0 -48
  114. package/python/opentrons_shared_data/protocol/models/protocol_schema_v6.py +0 -145
  115. package/python/opentrons_shared_data/protocol/models/protocol_schema_v7.py +0 -95
  116. package/python/opentrons_shared_data/protocol/models/protocol_schema_v8.py +0 -110
  117. package/python/opentrons_shared_data/protocol/models/shared_models.py +0 -111
  118. package/python/opentrons_shared_data/py.typed +0 -0
  119. package/python/opentrons_shared_data/robot/__init__.py +0 -33
  120. package/python/opentrons_shared_data/robot/dev_types.py +0 -37
  121. package/python/pytest.ini +0 -2
  122. package/python/setup.cfg +0 -5
  123. package/python/setup.py +0 -179
  124. package/python/tests/__init__.py +0 -1
  125. package/python/tests/conftest.py +0 -0
  126. package/python/tests/deck/__init__.py +0 -0
  127. package/python/tests/deck/test_list_names.py +0 -12
  128. package/python/tests/deck/test_position.py +0 -113
  129. package/python/tests/deck/test_typechecks.py +0 -28
  130. package/python/tests/errors/__init__.py +0 -1
  131. package/python/tests/errors/test_error_completeness.py +0 -19
  132. package/python/tests/errors/test_exceptions.py +0 -74
  133. package/python/tests/gripper/__init__.py +0 -0
  134. package/python/tests/gripper/test_definition.py +0 -30
  135. package/python/tests/gripper/test_load.py +0 -16
  136. package/python/tests/labware/__init__.py +0 -13
  137. package/python/tests/labware/test_typechecks.py +0 -21
  138. package/python/tests/module/__init__.py +0 -20
  139. package/python/tests/module/test_load.py +0 -49
  140. package/python/tests/module/test_typechecks.py +0 -34
  141. package/python/tests/pipette/__init__.py +0 -0
  142. package/python/tests/pipette/test_load_data.py +0 -103
  143. package/python/tests/pipette/test_mutable_configurations.py +0 -266
  144. package/python/tests/pipette/test_pipette_definition.py +0 -183
  145. package/python/tests/pipette/test_pipette_load_name_conversions.py +0 -222
  146. package/python/tests/pipette/test_typechecks.py +0 -50
  147. package/python/tests/pipette/test_validate_schema.py +0 -37
  148. package/python/tests/protocol/__init__.py +0 -15
  149. package/python/tests/protocol/test_protocol_schema_v6.py +0 -107
  150. package/python/tests/protocol/test_protocol_schema_v7.py +0 -34
  151. package/python/tests/protocol/test_protocol_schema_v8.py +0 -20
  152. package/python/tests/protocol/test_typechecks.py +0 -36
  153. package/python/tests/robot/__init__.py +0 -0
  154. 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
- })