@@ -102,8 +102,99 @@ async def test_touch_tip_implementation(
102
102
pipette_id = "abc" ,
103
103
labware_id = "123" ,
104
104
well_name = "A3" ,
105
- center_point = Point (x = 1 , y = 2 , z = 3 ),
106
105
radius = 0.456 ,
106
+ mm_from_edge = 0 ,
107
+ center_point = Point (x = 1 , y = 2 , z = 3 ),
108
+ )
109
+ ).then_return (
110
+ [
111
+ Waypoint (
112
+ position = Point (x = 11 , y = 22 , z = 33 ),
113
+ critical_point = CriticalPoint .XY_CENTER ,
114
+ ),
115
+ Waypoint (
116
+ position = Point (x = 44 , y = 55 , z = 66 ),
117
+ critical_point = CriticalPoint .XY_CENTER ,
118
+ ),
119
+ ]
120
+ )
121
+
122
+ decoy .when (
123
+ await mock_gantry_mover .move_to (
124
+ pipette_id = "abc" ,
125
+ waypoints = [
126
+ Waypoint (
127
+ position = Point (x = 11 , y = 22 , z = 33 ),
128
+ critical_point = CriticalPoint .XY_CENTER ,
129
+ ),
130
+ Waypoint (
131
+ position = Point (x = 44 , y = 55 , z = 66 ),
132
+ critical_point = CriticalPoint .XY_CENTER ,
133
+ ),
134
+ ],
135
+ speed = 9001 ,
136
+ )
137
+ ).then_return (Point (x = 4 , y = 5 , z = 6 ))
138
+
139
+ result = await subject .execute (params )
140
+
141
+ assert result == SuccessData (
142
+ public = TouchTipResult (position = DeckPoint (x = 4 , y = 5 , z = 6 )),
143
+ state_update = update_types .StateUpdate (
144
+ pipette_location = update_types .PipetteLocationUpdate (
145
+ pipette_id = "abc" ,
146
+ new_location = update_types .Well (labware_id = "123" , well_name = "A3" ),
147
+ new_deck_point = DeckPoint (x = 4 , y = 5 , z = 6 ),
148
+ )
149
+ ),
150
+ )
151
+
152
+
153
+ async def test_touch_tip_implementation_with_mm_to_edge (
154
+ decoy : Decoy ,
155
+ mock_state_view : StateView ,
156
+ mock_movement_handler : MovementHandler ,
157
+ mock_gantry_mover : GantryMover ,
158
+ subject : TouchTipImplementation ,
159
+ ) -> None :
160
+ """A TouchTip command should use mmFromEdge if provided."""
161
+ params = TouchTipParams (
162
+ pipetteId = "abc" ,
163
+ labwareId = "123" ,
164
+ wellName = "A3" ,
165
+ wellLocation = WellLocation (offset = WellOffset (x = 1 , y = 2 , z = 3 )),
166
+ mmFromEdge = 0.789 ,
167
+ speed = 42.0 ,
168
+ )
169
+
170
+ decoy .when (
171
+ await mock_movement_handler .move_to_well (
172
+ pipette_id = "abc" ,
173
+ labware_id = "123" ,
174
+ well_name = "A3" ,
175
+ well_location = WellLocation (offset = WellOffset (x = 1 , y = 2 , z = 3 )),
176
+ current_well = None ,
177
+ force_direct = False ,
178
+ minimum_z_height = None ,
179
+ speed = None ,
180
+ operation_volume = None ,
181
+ )
182
+ ).then_return (Point (x = 1 , y = 2 , z = 3 ))
183
+
184
+ decoy .when (
185
+ mock_state_view .pipettes .get_movement_speed (
186
+ pipette_id = "abc" , requested_speed = 42.0
187
+ )
188
+ ).then_return (9001 )
189
+
190
+ decoy .when (
191
+ mock_state_view .motion .get_touch_tip_waypoints (
192
+ pipette_id = "abc" ,
193
+ labware_id = "123" ,
194
+ well_name = "A3" ,
195
+ radius = 1.0 ,
196
+ mm_from_edge = 0.789 ,
197
+ center_point = Point (x = 1 , y = 2 , z = 3 ),
107
198
)
108
199
).then_return (
109
200
[
@@ -183,3 +274,20 @@ async def test_touch_tip_no_tip_racks(
183
274
184
275
with pytest .raises (errors .LabwareIsTipRackError ):
185
276
await subject .execute (params )
277
+
278
+
279
+ async def test_touch_tip_incompatible_arguments (
280
+ decoy : Decoy , mock_state_view : StateView , subject : TouchTipImplementation
281
+ ) -> None :
282
+ """It should disallow touch tip if radius and mmFromEdge is provided."""
283
+ params = TouchTipParams (
284
+ pipetteId = "abc" ,
285
+ labwareId = "123" ,
286
+ wellName = "A3" ,
287
+ wellLocation = WellLocation (),
288
+ radius = 1.23 ,
289
+ mmFromEdge = 4.56 ,
290
+ )
291
+
292
+ with pytest .raises (errors .TouchTipIncompatibleArgumentsError ):
293
+ await subject .execute (params )
0 commit comments