/* Ċ Ġ* ĠCopyright Ġ 2 0 2 1 ĠThe ĠAndroid ĠOpen ĠSource ĠProject Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġandroidx . compose . ui . test . injection scope . touch Ċ Ċ import Ġandroidx . compose . ui . geometry . Offset Ċ import Ġandroidx . compose . ui . geometry . is Finite Ċ import Ġandroidx . compose . ui . input . pointer . util . Velocity Tracker Ċ import Ġandroidx . compose . ui . test . Input Dispatcher . Companion . event Period Millis Ċ import Ġandroidx . compose . ui . test . Velocity Path Finder Ċ import Ġandroidx . compose . ui . test . util . is Almost Between Ċ import Ġandroidx . compose . ui . test . util . is Almost EqualTo Ċ import Ġandroidx . compose . ui . unit . Velocity Ċ import Ġandroidx . compose . ui . util . lerp Ċ import Ġcom . google . common . truth . Truth . assertThat Ċ import Ġorg . junit . Assert . fail Ċ import Ġorg . junit . Test Ċ import Ġorg . junit . runner . RunWith Ċ import Ġorg . junit . runners . Parameterized Ċ import Ġjava . lang . IllegalArgumentException Ċ import Ġkotlin . math . max Ċ import Ġkotlin . math . round ToInt Ċ import Ġkotlin . math . sqrt Ċ Ċ /** Ċ Ġ* ĠTest Ġto Ġcheck Ġif Ġ[ Velocity Path Finder . calculate Default Duration ] Ġcalculates Ġa Ġduration Ġfor Ċ Ġ* Ġwhich Ġit Ġis Ġpossible Ġto Ġgenerate Ġa Ġswipe Ġfrom Ġstart Ġto Ġend Ġwith Ġa Ġcertain Ġend Velocity . Ċ Ġ*/ Ċ @ RunWith ( Parameterized :: class ) Ċ class ĠVe locity Path Finder Calculate Duration Test ( private Ġval Ġconfig : ĠTest Config ) Ġ{ ĊĠĠĠ Ġdata Ġclass ĠTest Config ( ĊĠĠĠĠĠĠĠ Ġval Ġend : ĠOffset , ĊĠĠĠĠĠĠĠ Ġval Ġrequested Velocity : ĠFloat , ĊĠĠĠĠĠĠĠ Ġval Ġexpected Duration Millis : ĠLong ? Ġ= Ġnull , ĊĠĠĠĠĠĠĠ Ġval Ġexpect Suggestions : ĠBoolean Ġ= Ġfalse , ĊĠĠĠĠĠĠĠ Ġval Ġexpected Error : ĠRegex ? Ġ= Ġif Ġ( expect Suggestions ) Ġerror With Suggestions Ġelse Ġnull , ĊĠĠĠĠĠĠĠ Ġval Ġtolerance : ĠFloat Ġ= Ġ 0 . 1 f , ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠDistance Zero Ġ= ĠOffset . Zero ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠDistance 1 0 0 Ġ= ĠOffset ( 1 0 0 f , Ġ 0 f ) ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġerror Negative Velocity Ġ= ĠRegex (" Velocity Ġcannot Ġbe Ġ. *, Ġit Ġmust Ġbe Ġpositive ") ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġerror Positive Velocity Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRegex (" When Ġstart Ġ== Ġend ; Ġvelocity Ġcannot Ġbe Ġ. *, Ġit Ġmust Ġbe Ġ 0 f ") ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġerror With Suggestions Ġ= ĠRegex ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Unable Ġto Ġgenerate Ġa Ġswipe Ġgesture Ġbetween Ġ.* Ġand Ġ.* Ġthat Ġends Ġwith Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" velocity Ġof Ġ.* Ġpx / s , Ġwithout Ġgoing Ġoutside Ġof Ġthe Ġrange Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"\\ [ start \\. \\. end ] \\. ĠSuggest ed Ġfixes : Ġ. *" ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġsuggested Fixes Regex Ġ= ĠRegex ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" 1 \\. Ġset Ġvelocity Ġto Ġ( .* ) Ġpx / s Ġor Ġlower ; Ġor Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" 2 \\. Ġincrease Ġthe Ġdistance Ġbetween Ġthe Ġstart Ġand Ġend Ġto Ġ( .* ) Ġor Ġhigher " ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġ@ Parameterized . Parameters ( name Ġ= Ġ"{ 0 }") ĊĠĠĠĠĠĠĠ Ġfun Ġparams () Ġ= Ġmutable ListOf ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAn Ġessential Ġvalue Ġin Ġthe ĠVe locity Path Finder Ġis Ġ` d `, Ġcalculated Ġas ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ` d Ġ= Ġ 2 Ġ/ Ġvelocity Ġ* Ġ( end Ġ- Ġstart )`, Ġand Ġrepresents Ġthe Ġmaximum Ġtime Ġover Ġwhich Ġwe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcan Ġspread Ġout Ġa Ġgesture Ġgoing Ġfrom Ġstart Ġto Ġend Ġwhile Ġstill Ġfollowing Ġa Ġpolynomial ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthat Ġhas Ġv = velocity Ġat Ġthe Ġend . Ġ( Note Ġthat Ġthis Ġnecessarily Ġhas Ġv = 0 Ġat Ġthe Ġstart : ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġif Ġv < 0 Ġat Ġthe Ġstart , Ġthe Ġpath Ġwould Ġgo Ġout Ġof Ġthe Ġrange Ġ[ start , Ġend ], Ġand Ġif Ġv > 0 Ġwe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwould Ġar rive Ġat Ġthe Ġend Ġfaster .) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWithout Ġgoing Ġinto Ġdetails Ġas Ġto Ġwhy , Ġthere Ġare Ġbasically Ġ 3 Ġdifferent Ġranges Ġof Ġd ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġto Ġtest Ġfor : ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ 1 . Ġd Ġ< Ġ 4 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠ ĠThe Ġrequested Ġvelocity Ġis Ġso Ġhigh Ġthat Ġthe Ġ" slow est " Ġpolynomial Ġto Ġreach Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠ Ġstill Ġtakes Ġless Ġthan Ġ 4 0 ms , Ġwhich Ġis Ġthe Ġminimum Ġduration . ĠWe Ġexpect Ġthe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠ Ġduration Ġsuggestion Ġto Ġthrow Ġan ĠIllegalArgumentException , Ġand Ġsuggest Ġchanges ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠ Ġto Ġthe Ġinput Ġthat Ġwould Ġ_ just _ Ġtake Ġus Ġto Ġthat Ġ 4 0 ms Ġminimum . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ 2 . Ġd Ġ>= Ġ 1 0 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠ ĠWe Ġcan Ġmake Ġa Ġvalid Ġpath Ġwith Ġany Ġdesired Ġduration . ĠThe Ġsuggestion Ġp icks Ġa ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠ Ġdefault Ġof Ġ 2 0 0 ms . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ 3 . Ġ 4 0 Ġ<= Ġd Ġ< Ġ 1 0 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠ ĠThe Ġentire Ġgesture Ġmust Ġfollow Ġan Ġexact Ġpolynomial , Ġwhich Ġis Ġonly Ġpossible Ġif ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠ Ġthe Ġsuggested Ġduration Ġ< Ġd . ĠWe Ġexpect Ġthe Ġsuggestion Ġto Ġbe Ġfloor ( d ). ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠA Ġfew Ġother Ġscenarios Ġto Ġtest Ġfor Ġare : ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ- Ġstart Ġ== Ġend ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠ ĠGest ure Ġcan 't Ġmove Ġat Ġall , Ġso Ġvelocity Ġ_ must _ Ġbe Ġ 0 . ĠExpect Ġan Ġerror Ġotherwise . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ- Ġvelocity Ġ< Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠ ĠSimply Ġnot Ġpossible . ĠExpect Ġan Ġerror Ġalways . ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠTest Config ( Distance Zero , Ġ- 1 f , Ġexpected Error Ġ= Ġerror Negative Velocity ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTest Config ( Distance Zero , Ġ 0 f , Ġexpected Duration Millis Ġ= Ġ 2 0 0 L ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTest Config ( Distance Zero , Ġ 1 f , Ġexpected Error Ġ= Ġerror Positive Velocity ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTest Config ( Distance 1 0 0 , Ġ- 1 f , Ġexpected Error Ġ= Ġerror Negative Velocity ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTest Config ( Distance 1 0 0 , Ġ 0 f , Ġexpected Duration Millis Ġ= Ġ 2 0 0 L ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTest Config ( Distance 1 0 0 , Ġ 1 f , Ġexpected Duration Millis Ġ= Ġ 2 0 0 L ), ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠTest Config ( Distance 1 0 0 , Ġ 1 9 9 9 f , Ġexpected Duration Millis Ġ= Ġ 2 0 0 L , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtolerance Ġ= Ġ 1 f ), Ġ// Ġd Ġ> Ġ 1 0 0 ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTest Config ( Distance 1 0 0 , Ġ 2 0 0 0 f , Ġexpected Duration Millis Ġ= Ġ 1 0 0 L ), Ġ// Ġd Ġ= Ġ 1 0 0 ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTest Config ( Distance 1 0 0 , Ġ 2 4 8 0 f , Ġexpected Duration Millis Ġ= Ġ 8 0 L , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtolerance Ġ= Ġ 1 f ), Ġ// Ġd Ġâī Ī Ġ 8 0 . 6 5 ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTest Config ( Distance 1 0 0 , Ġ 5 0 0 0 f , Ġexpected Error Ġ= Ġerror With Suggestions ), Ġ// Ġd Ġ= Ġ 4 0 ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTest Config ( Distance 1 0 0 , Ġ 5 0 0 1 f , Ġexpected Error Ġ= Ġerror With Suggestions ), Ġ// Ġd Ġ< Ġ 4 0 ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( config . expected Error Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtest With Expected Error ( config , Ġtest Suggestions Ġ= Ġconfig . expect Suggestions ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtest Without Expected Error ( config ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġtest Without Expected Error ( config : ĠTest Config ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġactual Duration Ġ= ĠVe locity Path Finder . calculate Default Duration ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstart Ġ= ĠOffset . Zero , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġend Ġ= Ġconfig . end , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġend Velocity Ġ= Ġconfig . requested Velocity ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ ĠassertThat ( actual Duration ). isEqualTo ( config . expected Duration Millis ) ĊĊĠĠĠĠĠĠĠ Ġval Ġpath Finder Ġ= ĠVe locity Path Finder ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠstartPosition Ġ= ĠOffset . Zero , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġend Position Ġ= Ġconfig . end , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġend Velocity Ġ= Ġconfig . requested Velocity , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġduration Millis Ġ= Ġactual Duration ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġval Ġf Ġ= Ġpath Finder . generate Function () ĊĠĠĠĠĠĠĠ Ġval Ġvelocity Tracker Ġ= Ġsimulate Swipe ( f , Ġactual Duration ) ĊĠĠĠĠĠĠĠ Ġval Ġvelocity Ġ= Ġvelocity Tracker . calculate Velocity () ĊĊĠĠĠĠĠĠĠ ĠassertThat ( velocity . sum ()). is Within ( config . tolerance ). of ( config . requested Velocity ) ĊĠĠĠĠĠĠĠ Ġif Ġ( config . requested Velocity Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠDirection Ġof Ġvelocity Ġof Ġ 0 Ġis Ġundefined , Ġso Ġany Ġdirection Ġis Ġcorrect ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvelocity . to Offset (). normalize (). is Almost EqualTo ( config . end . normalize ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠAt Ġt Ġ= Ġ 0 , Ġthe Ġfunction Ġshould Ġreturn Ġthe Ġstart Ġposition Ġ( which Ġis ĠOffset . Zero Ġhere ) ĊĠĠĠĠĠĠĠ Ġf ( 0 ). is Almost EqualTo ( Offset . Zero ) ĊĠĠĠĠĠĠĠ Ġ// ĠAt Ġany Ġtime , Ġthe Ġfunction Ġshould Ġbe Ġbetween Ġthe Ġstart Ġand Ġend ĊĠĠĠĠĠĠĠ Ġfor Ġ( t Ġin Ġ 0 .. actual Duration ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( f ( t ). x ). is Almost Between ( 0 f , Ġconfig . end . x ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( f ( t ). y ). is Almost Between ( 0 f , Ġconfig . end . y ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠAt Ġt Ġ= Ġduration Millis , Ġthe Ġfunction Ġshould Ġreturn Ġthe Ġend Ġposition ĊĠĠĠĠĠĠĠ Ġf ( actual Duration ). is Almost EqualTo ( config . end ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġtest With Expected Error ( config : ĠTest Config , Ġtest Suggestions : ĠBoolean Ġ= Ġfalse ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠVe locity Path Finder . calculate Default Duration ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstart Ġ= ĠOffset . Zero , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġend Ġ= Ġconfig . end , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġend Velocity Ġ= Ġconfig . requested Velocity ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfail (" Expected Ġan ĠIllegalArgumentException ") ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIllegalArgumentException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( e . message ). matches ( config . expected Error !!. to Pattern ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( test Suggestions ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsuggested Fixes Ġ= Ġe . message !!. substring After (" Suggest ed Ġfixes : Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( max Velocity , Ġmin Distance ) Ġ= Ġget Suggestions ( suggest ed Fixes ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠVerify Ġthat Ġthe Ġsuggestions Ġchange Ġthe Ġcurrent Ġconfig ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( max Velocity ). is LessThan ( config . requested Velocity ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( min Distance ). is GreaterThan ( config . end . get Distance ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTry Ġjust Ġinside Ġthe Ġsuggested Ġvalue Ġrange ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtest Without Expected Error ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconfig . copy ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequested Velocity Ġ= Ġmax Velocity Ġ* Ġ 0 . 9 9 9 f , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġsuggestions Ġare Ġdesigned Ġto Ġhit Ġthe Ġ 4 0 L Ġboundary ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexpected Duration Millis Ġ= Ġ 4 0 L ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtest Without Expected Error ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconfig . copy ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġend Ġ= ĠOffset ( min Distance Ġ* Ġ 1 . 0 0 1 f , Ġ 0 f ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġsuggestions Ġare Ġdesigned Ġto Ġhit Ġthe Ġ 4 0 L Ġboundary ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexpected Duration Millis Ġ= Ġ 4 0 L ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTry Ġjust Ġoutside Ġthe Ġsuggested Ġvalue Ġrange ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtest With Expected Error ( config . copy ( requested Velocity Ġ= Ġmax Velocity Ġ* Ġ 1 . 0 0 1 f )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtest With Expected Error ( config . copy ( end Ġ= ĠOffset ( min Distance Ġ* Ġ 0 . 9 9 9 f , Ġ 0 f ))) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Suggestions ( suggest ed Fixes : ĠString ): ĠList < Float > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmatch Ġ= Ġsuggested Fixes Regex . match Ent ire ( suggest ed Fixes ) ĊĠĠĠĠĠĠĠ ĠassertThat ( match ). isNotNull () ĊĠĠĠĠĠĠĠ ĠassertThat ( match !!. groups ). has Size ( 3 ) ĊĠĠĠĠĠĠĠ Ġreturn Ġmatch . group Values . sub List ( 1 , Ġ 3 ). map Ġ{ Ġit . toFloat () Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsimulate Swipe ( f : Ġ( Long ) Ġ-> ĠOffset , Ġduration Millis : ĠLong ): ĠVe locity Tracker Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġvelocity Tracker Ġ= ĠVe locity Tracker () ĊĠĠĠĠĠĠĠ Ġval Ġsteps Ġ= Ġmax ( 1 , Ġ( duration Millis Ġ/ Ġevent Period Millis . toFloat ()). round ToInt ()) ĊĠĠĠĠĠĠĠ Ġfor Ġ( step Ġin Ġ 0 .. steps ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprogress Ġ= Ġstep Ġ/ Ġsteps . toFloat () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġt Ġ= Ġl erp ( 0 , Ġduration Millis , Ġprogress ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvelocity Tracker . add Position ( t , Ġf ( t )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġvelocity Tracker ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠOffset . normalize (): ĠOffset Ġ= ĊĠĠĠĠĠĠĠ Ġif Ġ( is Finite Ġ&& Ġthis Ġ!= ĠOffset . Zero ) Ġthis Ġ/ Ġget Distance () Ġelse Ġthis ĊĊĠĠĠ Ġprivate Ġfun ĠVe locity . to Offset (): ĠOffset Ġ= ĠOffset ( x , Ġy ) ĊĠĠĠ Ġprivate Ġfun ĠVe locity . sum (): ĠFloat Ġ= Ġsqrt ( x Ġ* Ġx Ġ+ Ġy Ġ* Ġy ) Ċ } Ċ