/* Ċ Ġ* ĠCopyright Ġ 2 0 1 9 Ġ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 . ui . core . test Ċ Ċ import Ġandroidx . compose . Composable Ċ import Ġandroidx . compose . state Ċ import Ġandroidx . compose . unary Plus Ċ import Ġandroidx . test . filters . Small Test Ċ import Ġandroidx . ui . core . Focus Manager Ambient Ċ import Ġandroidx . ui . core . Test Tag Ċ import Ġandroidx . ui . core . TextField Ċ import Ġandroidx . ui . core . TextInput Service Ambient Ċ import Ġandroidx . ui . core . input . Focus Manager Ċ import Ġandroidx . ui . input . Commit Text Edit Op Ċ import Ġandroidx . ui . input . Edit Operation Ċ import Ġandroidx . ui . input . Editor Style Ċ import Ġandroidx . ui . input . Input State Ċ import Ġandroidx . ui . input . Set Comp osing Region Edit Op Ċ import Ġandroidx . ui . input . TextInput Service Ċ import Ġandroidx . ui . test . create Compose Rule Ċ import Ġandroidx . ui . test . do Click Ċ import Ġandroidx . ui . test . findBy Tag Ċ import Ġandroidx . ui . test . waitFor Idle Compose Ċ import Ġcom . google . common . truth . Truth . assertThat Ċ import Ġcom . n ha ar man . mock it ok otlin 2 . any Ċ import Ġcom . n ha ar man . mock it ok otlin 2 . argument Captor Ċ import Ġcom . n ha ar man . mock it ok otlin 2 . at Least Once Ċ import Ġcom . n ha ar man . mock it ok otlin 2 . clear Inv ocations Ċ import Ġcom . n ha ar man . mock it ok otlin 2 . eq Ċ import Ġcom . n ha ar man . mock it ok otlin 2 . mock Ċ import Ġcom . n ha ar man . mock it ok otlin 2 . never Ċ import Ġcom . n ha ar man . mock it ok otlin 2 . times Ċ import Ġcom . n ha ar man . mock it ok otlin 2 . verify Ċ import Ġcom . n ha ar man . mock it ok otlin 2 . wh enever Ċ import Ġorg . junit . Rule Ċ import Ġorg . junit . Test Ċ import Ġorg . junit . runner . RunWith Ċ import Ġorg . junit . runners . JUnit 4 Ċ Ċ @ Small Test Ċ @ RunWith ( JUnit 4 :: class ) Ċ class ĠTextField Test Ġ{ ĊĠĠĠ Ġ@ get : Rule ĊĠĠĠ Ġval Ġcompose Test Rule Ġ= Ġcreate Compose Rule () ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtext Field _ focus In Semantics () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfocus Manager Ġ= Ġmock < Focus Manager >() ĊĠĠĠĠĠĠĠ Ġval Ġinput Service Ġ= Ġmock < TextInput Service >() ĊĠĠĠĠĠĠĠ Ġcompose Test Rule . setContent Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Ġ= Ġ+ state Ġ{ Ġ"" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFocus Manager Ambient . Provider ( value Ġ= Ġfocus Manager ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠText Input Service Ambient . Provider ( value Ġ= Ġinput Service ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTest Tag ( tag Ġ= Ġ" textField ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTextField ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Ġ= Ġstate . value , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Value Change Ġ= Ġ{ Ġstate . value Ġ= Ġit Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġeditor Style Ġ= ĠEditor Style () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ ĠfindBy Tag (" textField ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. do Click () ĊĊĠĠĠĠĠĠĠ Ġverify ( focus Manager , Ġtimes ( 1 )). request Focus ( any ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Composable ĊĠĠĠ Ġprivate Ġfun ĠTextField App () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstate Ġ= Ġ+ state Ġ{ Ġ"" Ġ} ĊĠĠĠĠĠĠĠ ĠTextField ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Ġ= Ġstate . value , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Value Change Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate . value Ġ= Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtext Field _ commit Texts () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfocus Manager Ġ= Ġmock < Focus Manager >() ĊĠĠĠĠĠĠĠ Ġval Ġtext Input Service Ġ= Ġmock < TextInput Service >() ĊĠĠĠĠĠĠĠ Ġval Ġinput Session Token Ġ= Ġ 1 0 Ġ// Ġany Ġpositive Ġnumber Ġis Ġfine . ĊĊĠĠĠĠĠĠĠ Ġ// ĠAlways Ġgive Ġfocus Ġto Ġthe Ġpassed Ġnode . ĊĠĠĠĠĠĠĠ Ġwhenever ( focus Manager . request Focus ( any ())). then Answer Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( it . arguments [ 0 ] Ġas ĠFocus Manager . Focus Node ). on Focus () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġwhenever ( textInput Service . start Input ( any (), Ġany (), Ġany (), Ġany (), Ġany ())) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. thenReturn ( input Session Token ) ĊĊĠĠĠĠĠĠĠ Ġcompose Test Rule . setContent Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFocus Manager Ambient . Provider ( value Ġ= Ġfocus Manager ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠText Input Service Ambient . Provider ( value Ġ= Ġtext Input Service ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTest Tag ( tag Ġ= Ġ" textField ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTextField App () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠPerform Ġclick Ġto Ġfocus Ġin . ĊĠĠĠĠĠĠĠ ĠfindBy Tag (" textField ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. do Click () ĊĊĠĠĠĠĠĠĠ Ġ// ĠVerify Ġstart Input Ġis Ġcalled Ġand Ġcapture Ġthe Ġcallback . ĊĠĠĠĠĠĠĠ Ġval Ġon Edit Command Captor Ġ= Ġargument Captor <( List < Edit Operation >) Ġ-> ĠUnit >() ĊĠĠĠĠĠĠĠ Ġverify ( textInput Service , Ġtimes ( 1 )). start Input ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinit Model Ġ= Ġany (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkeyboard Type Ġ= Ġany (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ ime Action Ġ= Ġany (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Edit Command Ġ= Ġon Edit Command Captor . capture (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon I me ActionPerformed Ġ= Ġany () ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ ĠassertThat ( on Edit Command Captor . all Values . size ). isEqualTo ( 1 ) ĊĠĠĠĠĠĠĠ Ġval Ġon Edit Command Callback Ġ= Ġon Edit Command Captor . first Value ĊĠĠĠĠĠĠĠ ĠassertThat ( on Edit Command Callback ). isNotNull () ĊĊĠĠĠĠĠĠĠ Ġ// ĠPerforms Ġinput Ġevents Ġ" 1 ", Ġ" a ", Ġ" 2 ", Ġ" b ", Ġ" 3 ". ĠOnly Ġnumbers Ġshould Ġremain . ĊĠĠĠĠĠĠĠ ĠarrayOf ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Commit Text Edit Op (" 1 ", Ġ 1 )), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Commit Text Edit Op (" a ", Ġ 1 )), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Commit Text Edit Op (" 2 ", Ġ 1 )), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Commit Text Edit Op (" b ", Ġ 1 )), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Commit Text Edit Op (" 3 ", Ġ 1 )) ĊĠĠĠĠĠĠĠ Ġ). forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcompose Test Rule . run On Ui Thread Ġ{ Ġon Edit Command Callback ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠwaitFor Idle Compose () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġcompose Test Rule . run On Ui Thread Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Captor Ġ= Ġargument Captor < Input State >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġverify ( textInput Service , Ġat Least Once ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. on State Updated ( eq ( input Session Token ), Ġstate Captor . capture ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠDon 't Ġcare Ġabout Ġthe Ġintermediate Ġstate Ġupdate . ĠIt Ġshould Ġeventually Ġbe Ġ" 1 a 2 b 3 ". ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( state Captor . last Value . text ). isEqualTo (" 1 a 2 b 3 ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Composable ĊĠĠĠ Ġprivate Ġfun ĠOnly Digits App () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstate Ġ= Ġ+ state Ġ{ Ġ"" Ġ} ĊĠĠĠĠĠĠĠ ĠTextField ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Ġ= Ġstate . value , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Value Change Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . all Ġ{ Ġit . is Digit () Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate . value Ġ= Ġit ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtext Field _ commit Texts _ state _ may _ not _ set () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfocus Manager Ġ= Ġmock < Focus Manager >() ĊĠĠĠĠĠĠĠ Ġval Ġtext Input Service Ġ= Ġmock < TextInput Service >() ĊĠĠĠĠĠĠĠ Ġval Ġinput Session Token Ġ= Ġ 1 0 Ġ// Ġany Ġpositive Ġnumber Ġis Ġfine . ĊĊĠĠĠĠĠĠĠ Ġ// ĠAlways Ġgive Ġfocus Ġto Ġthe Ġpassed Ġnode . ĊĠĠĠĠĠĠĠ Ġwhenever ( focus Manager . request Focus ( any ())). then Answer Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( it . arguments [ 0 ] Ġas ĠFocus Manager . Focus Node ). on Focus () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġwhenever ( textInput Service . start Input ( any (), Ġany (), Ġany (), Ġany (), Ġany ())) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. thenReturn ( input Session Token ) ĊĊĠĠĠĠĠĠĠ Ġcompose Test Rule . setContent Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFocus Manager Ambient . Provider ( value Ġ= Ġfocus Manager ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠText Input Service Ambient . Provider ( value Ġ= Ġtext Input Service ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTest Tag ( tag Ġ= Ġ" textField ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOnly Digits App () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠPerform Ġclick Ġto Ġfocus Ġin . ĊĠĠĠĠĠĠĠ Ġval Ġelement Ġ= ĠfindBy Tag (" textField ") ĊĠĠĠĠĠĠĠ Ġelement . do Click () ĊĊĠĠĠĠĠĠĠ Ġ// ĠVerify Ġstart Input Ġis Ġcalled Ġand Ġcapture Ġthe Ġcallback . ĊĠĠĠĠĠĠĠ Ġval Ġon Edit Command Captor Ġ= Ġargument Captor <( List < Edit Operation >) Ġ-> ĠUnit >() ĊĠĠĠĠĠĠĠ Ġverify ( textInput Service , Ġtimes ( 1 )). start Input ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinit Model Ġ= Ġany (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkeyboard Type Ġ= Ġany (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ ime Action Ġ= Ġany (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Edit Command Ġ= Ġon Edit Command Captor . capture (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon I me ActionPerformed Ġ= Ġany () ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ ĠassertThat ( on Edit Command Captor . all Values . size ). isEqualTo ( 1 ) ĊĠĠĠĠĠĠĠ Ġval Ġon Edit Command Callback Ġ= Ġon Edit Command Captor . first Value ĊĠĠĠĠĠĠĠ ĠassertThat ( on Edit Command Callback ). isNotNull () ĊĊĠĠĠĠĠĠĠ Ġ// ĠPerforms Ġinput Ġevents Ġ" 1 ", Ġ" a ", Ġ" 2 ", Ġ" b ", Ġ" 3 ". ĠOnly Ġnumbers Ġshould Ġremain . ĊĠĠĠĠĠĠĠ ĠarrayOf ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Commit Text Edit Op (" 1 ", Ġ 1 )), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Commit Text Edit Op (" a ", Ġ 1 )), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Commit Text Edit Op (" 2 ", Ġ 1 )), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Commit Text Edit Op (" b ", Ġ 1 )), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( Commit Text Edit Op (" 3 ", Ġ 1 )) ĊĠĠĠĠĠĠĠ Ġ). forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcompose Test Rule . run On Ui Thread Ġ{ Ġon Edit Command Callback ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠwaitFor Idle Compose () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġcompose Test Rule . run On Ui Thread Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Captor Ġ= Ġargument Captor < Input State >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġverify ( textInput Service , Ġat Least Once ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. on State Updated ( eq ( input Session Token ), Ġstate Captor . capture ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠDon 't Ġcare Ġabout Ġthe Ġintermediate Ġstate Ġupdate . ĠIt Ġshould Ġeventually Ġbe Ġ" 1 2 3 " Ġsince ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthe Ġreject s Ġif Ġthe Ġincoming Ġmodel Ġcontains Ġal ph ab ets . ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( state Captor . last Value . text ). isEqualTo (" 1 2 3 ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ