4
4
5
5
from opentrons .protocol_engine .errors .exceptions import (
6
6
MustHomeError ,
7
+ PipetteNotReadyToAspirateError ,
7
8
TipNotAttachedError ,
8
9
TipNotEmptyError ,
9
10
)
37
38
PipettingHandler ,
38
39
)
39
40
from opentrons .protocol_engine .resources .model_utils import ModelUtils
40
- from opentrons .protocol_engine .types import LoadedPipette
41
41
42
42
43
43
EitherImplementationType = Union [
@@ -84,12 +84,14 @@ def result_type(types: tuple[object, object, EitherResultType]) -> EitherResultT
84
84
@pytest .fixture
85
85
def subject (
86
86
implementation_type : EitherImplementationType ,
87
+ state_view : StateView ,
87
88
movement : MovementHandler ,
88
89
pipetting : PipettingHandler ,
89
90
model_utils : ModelUtils ,
90
91
) -> Union [LiquidProbeImplementation , TryLiquidProbeImplementation ]:
91
92
"""Get the implementation subject."""
92
93
return implementation_type (
94
+ state_view = state_view ,
93
95
pipetting = pipetting ,
94
96
movement = movement ,
95
97
model_utils = model_utils ,
@@ -99,6 +101,7 @@ def subject(
99
101
async def test_liquid_probe_implementation_no_prep (
100
102
decoy : Decoy ,
101
103
movement : MovementHandler ,
104
+ state_view : StateView ,
102
105
pipetting : PipettingHandler ,
103
106
subject : EitherImplementation ,
104
107
params_type : EitherParamsType ,
@@ -114,7 +117,9 @@ async def test_liquid_probe_implementation_no_prep(
114
117
wellLocation = location ,
115
118
)
116
119
117
- decoy .when (pipetting .get_is_ready_to_aspirate (pipette_id = "abc" )).then_return (True )
120
+ decoy .when (state_view .pipettes .get_aspirated_volume (pipette_id = "abc" )).then_return (
121
+ 0
122
+ )
118
123
119
124
decoy .when (
120
125
await movement .move_to_well (
@@ -143,69 +148,9 @@ async def test_liquid_probe_implementation_no_prep(
143
148
)
144
149
145
150
146
- async def test_liquid_probe_implementation_with_prep (
147
- decoy : Decoy ,
148
- state_view : StateView ,
149
- movement : MovementHandler ,
150
- pipetting : PipettingHandler ,
151
- subject : EitherImplementation ,
152
- params_type : EitherParamsType ,
153
- result_type : EitherResultType ,
154
- ) -> None :
155
- """A Liquid Probe should have an execution implementation with preparing to aspirate."""
156
- location = WellLocation (origin = WellOrigin .TOP , offset = WellOffset (x = 0 , y = 0 , z = 2 ))
157
-
158
- data = params_type (
159
- pipetteId = "abc" ,
160
- labwareId = "123" ,
161
- wellName = "A3" ,
162
- wellLocation = location ,
163
- )
164
-
165
- decoy .when (pipetting .get_is_ready_to_aspirate (pipette_id = "abc" )).then_return (False )
166
-
167
- decoy .when (state_view .pipettes .get (pipette_id = "abc" )).then_return (
168
- LoadedPipette .construct ( # type:ignore[call-arg]
169
- mount = MountType .LEFT
170
- )
171
- )
172
- decoy .when (
173
- await movement .move_to_well (
174
- pipette_id = "abc" , labware_id = "123" , well_name = "A3" , well_location = location
175
- ),
176
- ).then_return (Point (x = 1 , y = 2 , z = 3 ))
177
-
178
- decoy .when (
179
- await pipetting .liquid_probe_in_place (
180
- pipette_id = "abc" ,
181
- labware_id = "123" ,
182
- well_name = "A3" ,
183
- well_location = location ,
184
- ),
185
- ).then_return (15.0 )
186
-
187
- result = await subject .execute (data )
188
-
189
- assert type (result .public ) is result_type # Pydantic v1 only compares the fields.
190
- assert result == SuccessData (
191
- public = result_type (z_position = 15.0 , position = DeckPoint (x = 1 , y = 2 , z = 3 )),
192
- private = None ,
193
- )
194
-
195
- decoy .verify (
196
- await movement .move_to_well (
197
- pipette_id = "abc" ,
198
- labware_id = "123" ,
199
- well_name = "A3" ,
200
- well_location = WellLocation (
201
- origin = WellOrigin .TOP , offset = WellOffset (x = 0 , y = 0 , z = 2 )
202
- ),
203
- ),
204
- )
205
-
206
-
207
151
async def test_liquid_not_found_error (
208
152
decoy : Decoy ,
153
+ state_view : StateView ,
209
154
movement : MovementHandler ,
210
155
pipetting : PipettingHandler ,
211
156
subject : EitherImplementation ,
@@ -232,9 +177,7 @@ async def test_liquid_not_found_error(
232
177
wellLocation = well_location ,
233
178
)
234
179
235
- decoy .when (pipetting .get_is_ready_to_aspirate (pipette_id = pipette_id )).then_return (
236
- True
237
- )
180
+ decoy .when (state_view .pipettes .get_aspirated_volume (pipette_id )).then_return (0 )
238
181
239
182
decoy .when (
240
183
await movement .move_to_well (
@@ -282,11 +225,11 @@ async def test_liquid_not_found_error(
282
225
283
226
async def test_liquid_probe_tip_checking (
284
227
decoy : Decoy ,
285
- pipetting : PipettingHandler ,
228
+ state_view : StateView ,
286
229
subject : EitherImplementation ,
287
230
params_type : EitherParamsType ,
288
231
) -> None :
289
- """It should return a TipNotAttached error if the hardware API indicates that."""
232
+ """It should raise a TipNotAttached error if the state view indicates that."""
290
233
pipette_id = "pipette-id"
291
234
labware_id = "labware-id"
292
235
well_name = "well-name"
@@ -301,18 +244,42 @@ async def test_liquid_probe_tip_checking(
301
244
wellLocation = well_location ,
302
245
)
303
246
304
- decoy .when (
305
- pipetting .get_is_ready_to_aspirate (
306
- pipette_id = pipette_id ,
307
- ),
308
- ).then_raise (TipNotAttachedError ())
247
+ decoy .when (state_view .pipettes .get_aspirated_volume (pipette_id )).then_raise (
248
+ TipNotAttachedError ()
249
+ )
309
250
with pytest .raises (TipNotAttachedError ):
310
251
await subject .execute (data )
311
252
312
253
254
+ async def test_liquid_probe_plunger_preparedness_checking (
255
+ decoy : Decoy ,
256
+ state_view : StateView ,
257
+ subject : EitherImplementation ,
258
+ params_type : EitherParamsType ,
259
+ ) -> None :
260
+ """It should raise a PipetteNotReadyToAspirate error if the state view indicates that."""
261
+ pipette_id = "pipette-id"
262
+ labware_id = "labware-id"
263
+ well_name = "well-name"
264
+ well_location = WellLocation (
265
+ origin = WellOrigin .BOTTOM , offset = WellOffset (x = 0 , y = 0 , z = 1 )
266
+ )
267
+
268
+ data = params_type (
269
+ pipetteId = pipette_id ,
270
+ labwareId = labware_id ,
271
+ wellName = well_name ,
272
+ wellLocation = well_location ,
273
+ )
274
+
275
+ decoy .when (state_view .pipettes .get_aspirated_volume (pipette_id )).then_return (None )
276
+ with pytest .raises (PipetteNotReadyToAspirateError ):
277
+ await subject .execute (data )
278
+
279
+
313
280
async def test_liquid_probe_volume_checking (
314
281
decoy : Decoy ,
315
- pipetting : PipettingHandler ,
282
+ state_view : StateView ,
316
283
subject : EitherImplementation ,
317
284
params_type : EitherParamsType ,
318
285
) -> None :
@@ -330,15 +297,23 @@ async def test_liquid_probe_volume_checking(
330
297
wellName = well_name ,
331
298
wellLocation = well_location ,
332
299
)
300
+
333
301
decoy .when (
334
- pipetting . get_is_empty (pipette_id = pipette_id ),
335
- ).then_return (False )
302
+ state_view . pipettes . get_aspirated_volume (pipette_id = pipette_id ),
303
+ ).then_return (123 )
336
304
with pytest .raises (TipNotEmptyError ):
337
305
await subject .execute (data )
338
306
307
+ decoy .when (
308
+ state_view .pipettes .get_aspirated_volume (pipette_id = pipette_id ),
309
+ ).then_return (None )
310
+ with pytest .raises (PipetteNotReadyToAspirateError ):
311
+ await subject .execute (data )
312
+
339
313
340
314
async def test_liquid_probe_location_checking (
341
315
decoy : Decoy ,
316
+ state_view : StateView ,
342
317
movement : MovementHandler ,
343
318
subject : EitherImplementation ,
344
319
params_type : EitherParamsType ,
@@ -357,6 +332,7 @@ async def test_liquid_probe_location_checking(
357
332
wellName = well_name ,
358
333
wellLocation = well_location ,
359
334
)
335
+ decoy .when (state_view .pipettes .get_aspirated_volume (pipette_id )).then_return (0 )
360
336
decoy .when (
361
337
await movement .check_for_valid_position (
362
338
mount = MountType .LEFT ,
0 commit comments