/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 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 Ġcom . android . tools . idea . databinding . index Ċ Ċ import Ġcom . android . tools . idea . testing . Android Project Rule Ċ import Ġcom . google . common . truth . Truth . assertThat Ċ import Ġcom . intellij . openapi . command . Write Command Action Ċ import Ġcom . intellij . openapi . project . Project Ċ import Ġcom . intellij . openapi . util . Text Range Ċ import Ġcom . intellij . psi . Psi Document Manager Ċ import Ġcom . intellij . psi . Psi Element Ċ import Ġcom . intellij . psi . Psi File Ċ import Ġcom . intellij . psi . Syntax Tra verser Ċ import Ġcom . intellij . psi . xml . XmlAttribute Ċ import Ġcom . intellij . psi . xml . Xml Tag Ċ import Ġcom . intellij . test Framework . Ed t Rule Ċ import Ġcom . intellij . test Framework . Runs In Ed t Ċ import Ġcom . intellij . test Framework . fixtures . Code Insight TestFixture Ċ import Ġcom . intellij . util . indexing . FileContent Impl Ċ import Ġcom . intellij . util . io . Data External izer Ċ import Ġcom . intellij . util . ui . UI Util Ċ import Ġorg . junit . Rule Ċ import Ġorg . junit . Test Ċ import Ġorg . junit . rules . Rule Chain Ċ import Ġjava . io . ByteArray InputStream Ċ import Ġjava . io . ByteArray OutputStream Ċ import Ġjava . io . Data InputStream Ċ import Ġjava . io . Data OutputStream Ċ Ċ class ĠBinding Xml Index Test Ġ{ ĊĠ Ġprivate Ġval Ġproject Rule Ġ= ĠAndroid Project Rule . on Disk () ĊĊĠ Ġ@ get : Rule ĊĠ Ġval Ġrule Chain Ġ= ĠRule Chain . outer Rule ( project Rule ). around ( Ed t Rule ()) !! ĊĊĠ Ġprivate Ġval Ġfixture : ĠCode Insight TestFixture Ġby Ġlazy Ġ{ ĊĠĠĠ Ġproject Rule . fixture ĊĠ Ġ} ĊĊĠ Ġprivate Ġlateinit Ġvar Ġpsi File : ĠPsi File ĊĊĠ Ġprivate Ġval Ġproject : ĠProject ĊĠĠĠ Ġget () Ġ= Ġproject Rule . project ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġindex Data Binding Layout () Ġ{ ĊĠĠĠ Ġval Ġfile Ġ= Ġfixture . configure By Text (" layout . xml ", Ġ""" ĊĠĠĠĠĠ Ġ< layout > ĊĠĠĠĠĠĠĠ Ġ< data Ġclass =" a . b . c . Custom Binding "> ĊĠĠĠĠĠĠĠĠĠ Ġ< import Ġtype =" C "/> ĊĠĠĠĠĠĠĠĠĠ Ġ< import Ġtype =" Map & lt ; D & gt ;" Ġalias =" Dee " Ġ/> ĊĠĠĠĠĠĠĠĠĠ Ġ< variable Ġtype =" A " Ġname =" ex 1 "/> ĊĠĠĠĠĠĠĠĠĠ Ġ< variable Ġtype =" B " Ġname =" ex 2 "/> ĊĠĠĠĠĠĠĠĠĠ Ġ< variable Ġtype =" List & lt ; E >" Ġname =" ex 3 "/> ĊĠĠĠĠĠĠĠ Ġ</ data > ĊĠĠĠĠĠ Ġ</ layout > ĊĠĠĠ Ġ""" . trim Indent ()). virtual File ĊĠĠĠ Ġval Ġbinding Xml Index Ġ= ĠBinding Xml Index () ĊĠĠĠ Ġval Ġmap Ġ= Ġbinding Xml Index . indexer . map ( FileContent Impl . create By File ( file )) ĊĊĠĠĠ ĠassertThat ( map ). has Size ( 1 ) ĊĊĠĠĠ Ġval Ġdata Ġ= Ġmap . values . first () ĊĠĠĠ ĠassertThat ( data . layout Type ). isEqualTo ( Binding Layout Type . DATA _ BINDING _ LAYOUT ) ĊĠĠĠ ĠassertThat ( data . root Tag ). isEqualTo (" layout ") ĊĠĠĠ ĠassertThat ( data . custom Binding Name ). isEqualTo (" a . b . c . Custom Binding ") ĊĠĠĠ ĠassertThat ( data . imports ). contains Exactly ( Import Data (" C ", Ġnull ), ĠImport Data (" Map < D >", Ġ" Dee ")) ĊĠĠĠ ĠassertThat ( data . variables ). contains Exactly ( ĊĠĠĠĠĠ ĠVariable Data (" ex 1 ", Ġ" A "), ĊĠĠĠĠĠ ĠVariable Data (" ex 2 ", Ġ" B "), ĊĠĠĠĠĠ ĠVariable Data (" ex 3 ", Ġ" List < E > ")) ĊĠĠĠ ĠassertThat ( data . view Ids ). isEmpty () ĊĊĠĠĠ Ġverify Serialization Logic ( binding Xml Index . value External izer , Ġdata ) ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġindex View Binding Layout () Ġ{ ĊĠĠĠ Ġval Ġfile Ġ= Ġfixture . configure By Text (" layout . xml ", Ġ""" ĊĠĠĠĠĠ Ġ< constraint _ layout Ġxmlns : android =" http :// schemas . android . com / apk / res / android "> ĊĠĠĠĠĠĠĠ Ġ< TextView Ġandroid : id ="@ + id / test Id 2 "/> ĊĠĠĠĠĠ Ġ</ constraint _ layout > ĊĠĠĠ Ġ""" . trim Indent ()). virtual File ĊĠĠĠ Ġval Ġbinding Xml Index Ġ= ĠBinding Xml Index () ĊĠĠĠ Ġval Ġmap Ġ= Ġbinding Xml Index . indexer . map ( FileContent Impl . create By File ( file )) ĊĊĠĠĠ Ġval Ġdata Ġ= Ġmap . values . first () ĊĠĠĠ ĠassertThat ( data . layout Type ). isEqualTo ( Binding Layout Type . PLAIN _ LAYOUT ) ĊĠĠĠ ĠassertThat ( data . root Tag ). isEqualTo (" constraint _ layout ") ĊĠĠĠ ĠassertThat ( data . custom Binding Name ). isNull () ĊĠĠĠ ĠassertThat ( data . view Binding Ignore ). isFalse () ĊĠĠĠ ĠassertThat ( data . imports ). isEmpty () ĊĠĠĠ ĠassertThat ( data . variables ). isEmpty () ĊĠĠĠ ĠassertThat ( data . view Ids ). contains Exactly ( View Id Data (" test Id 2 ", Ġ" TextView ", Ġnull )) ĊĊĠĠĠ Ġverify Serialization Logic ( binding Xml Index . value External izer , Ġdata ) ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġindex Binding Layout Sk ips Comments () Ġ{ ĊĠĠĠ Ġval Ġfile Ġ= Ġfixture . configure By Text ( ĊĠĠĠĠĠ Ġ" layout . xml ", ĊĠĠĠĠĠ Ġ// Ġlanguage = XML ĊĠĠĠĠĠ Ġ""" ĊĠĠĠĠĠ Ġ<!-- ĠLead ing Ġcomment Ġ--> ĊĠĠĠĠĠ Ġ< constraint _ layout Ġxmlns : android =" http :// schemas . android . com / apk / res / android "> ĊĠĠĠĠĠĠĠ Ġ<!-- ĠNorm ally Ġ& Ġun escaped Ġisn 't Ġallowed Ġbut Ġshould Ġbe ĠOK Ġin Ġa Ġcomment Ġ--> ĊĠĠĠĠĠĠĠ Ġ< TextView Ġandroid : id ="@ + id / test Id 1 "/> ĊĠĠĠĠĠĠĠ Ġ<!-- ĠComment Ġin Ġthe Ġmiddle Ġ--> ĊĠĠĠĠĠĠĠ Ġ< Button Ġandroid : id ="@ + id / test Id 2 "/> Ġ<!-- ĠSame Ġline Ġcomment Ġ--> ĊĠĠĠĠĠ Ġ</ constraint _ layout > ĊĠĠĠĠĠ Ġ<!-- ĠTr ailing Ġcomment Ġthat Ġwe Ġ" forgot " Ġto Ġclose ĊĠĠĠ Ġ""" . trim Indent ()). virtual File ĊĠĠĠ Ġval Ġbinding Xml Index Ġ= ĠBinding Xml Index () ĊĠĠĠ Ġval Ġmap Ġ= Ġbinding Xml Index . indexer . map ( FileContent Impl . create By File ( file )) ĊĊĠĠĠ Ġval Ġdata Ġ= Ġmap . values . first () ĊĠĠĠ ĠassertThat ( data . layout Type ). isEqualTo ( Binding Layout Type . PLAIN _ LAYOUT ) ĊĠĠĠ ĠassertThat ( data . root Tag ). isEqualTo (" constraint _ layout ") ĊĠĠĠ ĠassertThat ( data . custom Binding Name ). isNull () ĊĠĠĠ ĠassertThat ( data . view Binding Ignore ). isFalse () ĊĠĠĠ ĠassertThat ( data . imports ). isEmpty () ĊĠĠĠ ĠassertThat ( data . variables ). isEmpty () ĊĠĠĠ ĠassertThat ( data . view Ids ). contains Exactly ( View Id Data (" test Id 1 ", Ġ" TextView ", Ġnull ), ĠView Id Data (" test Id 2 ", Ġ" Button ", Ġnull )) ĊĊĠĠĠ Ġverify Serialization Logic ( binding Xml Index . value External izer , Ġdata ) ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġindex View Binding Ignore Layout () Ġ{ ĊĠĠĠ Ġval Ġfile Ġ= Ġfixture . configure By Text (" layout . xml ", Ġ""" ĊĠĠĠĠĠ Ġ< constraint _ layout Ġxmlns : android =" http :// schemas . android . com / apk / res / android " ĊĠĠĠĠĠĠĠ Ġxmlns : tools =" http :// schemas . android . com / tools " ĊĠĠĠĠĠĠĠ Ġtools : view Binding Ignore =" true "> ĊĠĠĠĠĠĠĠ Ġ< TextView Ġandroid : id ="@ + id / test Id 2 "/> ĊĠĠĠĠĠ Ġ</ constraint _ layout > ĊĠĠĠ Ġ""" . trim Indent ()). virtual File ĊĠĠĠ Ġval Ġbinding Xml Index Ġ= ĠBinding Xml Index () ĊĠĠĠ Ġval Ġmap Ġ= Ġbinding Xml Index . indexer . map ( FileContent Impl . create By File ( file )) ĊĊĠĠĠ Ġval Ġdata Ġ= Ġmap . values . first () ĊĠĠĠ ĠassertThat ( data . layout Type ). isEqualTo ( Binding Layout Type . PLAIN _ LAYOUT ) ĊĠĠĠ ĠassertThat ( data . root Tag ). isEqualTo (" constraint _ layout ") ĊĠĠĠ ĠassertThat ( data . custom Binding Name ). isNull () ĊĠĠĠ ĠassertThat ( data . view Binding Ignore ). isTrue () ĊĠĠĠ ĠassertThat ( data . imports ). isEmpty () ĊĠĠĠ ĠassertThat ( data . variables ). isEmpty () ĊĠĠĠ ĠassertThat ( data . view Ids ). contains Exactly ( View Id Data (" test Id 2 ", Ġ" TextView ", Ġnull )) ĊĊĠĠĠ Ġverify Serialization Logic ( binding Xml Index . value External izer , Ġdata ) ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġindex Layout Ids () Ġ{ ĊĠĠĠ Ġval Ġfile Ġ= Ġfixture . configure By Text (" layout . xml ", Ġ""" ĊĠĠĠĠĠ Ġ< layout Ġxmlns : android =" http :// schemas . android . com / apk / res / android "> ĊĠĠĠĠĠĠĠ Ġ< TextView Ġandroid : id ="@ + id / test Id 2 "/> ĊĠĠĠĠĠĠĠ Ġ< TextView Ġandroid : id ="@ id / test Id 3 "/> ĊĠĠĠĠĠĠĠ Ġ< TextView Ġandroid : id ="@ + id / test Id 1 "/> ĊĠĠĠĠĠĠĠ Ġ< Button Ġandroid : id ="@ id / android : test Id 7 "/> ĊĠĠĠĠĠĠĠ Ġ< CheckBox Ġandroid : id ="@ android : id / test Id 8 "/> ĊĠĠĠĠĠĠĠ Ġ< DatePicker Ġandroid : id ="@ + id / android : test Id 9 "/> ĊĠĠĠĠĠĠĠ Ġ< ProgressBar Ġandroid : id ="@ android : id / android : test Id 1 0 "/> ĊĠĠĠĠĠĠĠ Ġ< Number Picker Ġandroid : id =" invalid "/> ĊĠĠĠĠĠĠĠ Ġ< view Ġandroid : id ="@ + id / test Id 4 " Ġandroid : class =" com . example . class "/> ĊĠĠĠĠĠĠĠ Ġ< include Ġandroid : id ="@ + id / test Id 5 " Ġlayout =" this _ other _ layout "/> ĊĠĠĠĠĠĠĠ Ġ< merge Ġandroid : id ="@ + id / test Id 6 " Ġlayout =" this _ other _ layout "/> ĊĠĠĠĠĠ Ġ</ layout > ĊĠĠĠ Ġ""" . trim Indent ()). virtual File ĊĠĠĠ Ġval Ġbinding Xml Index Ġ= ĠBinding Xml Index () ĊĠĠĠ Ġval Ġmap Ġ= Ġbinding Xml Index . indexer . map ( FileContent Impl . create By File ( file )) ĊĊĠĠĠ Ġval Ġdata Ġ= Ġmap . values . first () ĊĠĠĠ ĠassertThat ( data . view Ids . toList ()). contains Exactly ( ĊĠĠĠĠĠ ĠView Id Data (" test Id 2 ", Ġ" TextView ", Ġnull ), ĊĠĠĠĠĠ ĠView Id Data (" test Id 3 ", Ġ" TextView ", Ġnull ), ĊĠĠĠĠĠ ĠView Id Data (" test Id 1 ", Ġ" TextView ", Ġnull ), ĊĠĠĠĠĠ ĠView Id Data (" test Id 7 ", Ġ" Button ", Ġnull ), ĊĠĠĠĠĠ ĠView Id Data (" test Id 8 ", Ġ" CheckBox ", Ġnull ), ĊĠĠĠĠĠ ĠView Id Data (" test Id 9 ", Ġ" DatePicker ", Ġnull ), ĊĠĠĠĠĠ Ġ// ĠTODO ( b / 1 4 1 0 1 3 4 4 8 ): ĠThis Ġshould Ġjust Ġbe Ġ" test Id 1 0 ", Ġupdate Ġafter ĠResource Url . parse Ġis Ġfixed ĊĠĠĠĠĠ ĠView Id Data (" android : test Id 1 0 ", Ġ" ProgressBar ", Ġnull ), ĊĠĠĠĠĠ ĠView Id Data (" test Id 4 ", Ġ" com . example . class ", Ġnull ), ĊĠĠĠĠĠ ĠView Id Data (" test Id 5 ", Ġ" include ", Ġ" this _ other _ layout "), ĊĠĠĠĠĠ ĠView Id Data (" test Id 6 ", Ġ" merge ", Ġ" this _ other _ layout ") ĊĠĠĠ Ġ). in Order () ĊĊĠĠĠ Ġverify Serialization Logic ( binding Xml Index . value External izer , Ġdata ) ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġcan Index Very Large Xml Files () Ġ{ ĊĠĠĠ Ġ// ĠXML Ġparsing Ġhappens Ġin Ġchunks Ġof Ġ~ 8 K , Ġso Ġmake Ġsure Ġwe Ġfeed Ġenough Ġtext Ġto Ġstress Ġthe Ġsystem ĊĠĠĠ Ġ// Ġthat Ġpatches Ġthe Ġchunks Ġtogether . ĊĠĠĠ Ġval Ġlayout Xml Ġ= Ġbuild String Ġ{ ĊĠĠĠĠĠ Ġappend (""" < layout Ġxmlns : android =" http :// schemas . android . com / apk / res / android "> """) ĊĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 1 .. 2 0 0 0 0 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġappend (""" < TextView Ġandroid : id ="@ + id / test Id $ i "/> """) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġappend ("</ layout >") ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġfile Ġ= Ġfixture . configure By Text (" layout . xml ", Ġlayout Xml ). virtual File ĊĊĠĠĠ Ġval Ġbinding Xml Index Ġ= ĠBinding Xml Index () ĊĠĠĠ Ġval Ġmap Ġ= Ġbinding Xml Index . indexer . map ( FileContent Impl . create By File ( file )) ĊĊĠĠĠ Ġval Ġdata Ġ= Ġmap . values . first () ĊĠĠĠ Ġ// ĠMake Ġsure Ġwe Ġdidn 't Ġdrop Ġa Ġsingle Ġitem ĊĠĠĠ ĠassertThat ( data . view Ids . size ). isEqualTo ( 2 0 0 0 0 ) ĊĠĠĠ ĠassertThat ( data . view Ids . first (). id ). isEqualTo (" test Id 1 ") ĊĠĠĠ ĠassertThat ( data . view Ids . last (). id ). isEqualTo (" test Id 2 0 0 0 0 ") ĊĊĠĠĠ Ġverify Serialization Logic ( binding Xml Index . value External izer , Ġdata ) ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġindex DoesNot Throw Exception If Encounter ing Un related Xml () Ġ{ ĊĠĠĠ Ġval Ġfile Ġ= Ġfixture . configure By Text ( ĊĠĠĠĠĠ Ġ" not - really - a - layout . xml ", ĊĠĠĠĠĠ Ġ// Ġlanguage = XML ĊĠĠĠĠĠ Ġ""" ĊĠĠĠĠĠĠĠ Ġ<? xml Ġversion =" 1 . 0 " Ġencoding =" utf - 8 "?> ĊĠĠĠĠĠĠĠ Ġ< manifest Ġxmlns : android =" http :// schemas . android . com / apk / res / android " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpackage =" com . example . layout . binding "> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ< application Ġandroid : label =" Binding Xml Index ĠTest " Ġ/> ĊĠĠĠĠĠĠĠ Ġ</ manifest > ĊĠĠĠ Ġ""" . trim Indent ()). virtual File ĊĊĠĠĠ Ġval Ġbinding Xml Index Ġ= ĠBinding Xml Index () ĊĠĠĠ Ġbinding Xml Index . indexer . map ( FileContent Impl . create By File ( file )) ĊĠĠĠ Ġ// ĠIf Ġwe Ġgot Ġhere , Ġno Ġexception Ġwas Ġthrown ĊĠ Ġ} ĊĊĊĠ Ġ@ Test ĊĠ Ġ@ Runs In Ed t ĊĠ Ġfun Ġtest Add Id To View () Ġ{ ĊĠĠĠ Ġsetup With Layout File ( ĊĠĠĠĠĠ Ġ""" ĊĠĠĠĠĠĠĠ Ġ< layout Ġxmlns : android =" http :// schemas . android . com / apk / res / android "> ĊĠĠĠĠĠĠĠĠĠ Ġ< LinearLayout ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : orientation =" vertical " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : layout _ width =" fill _ parent " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : layout _ height =" fill _ parent "> ĊĠĠĠĠĠĠĠĠĠ Ġ</ LinearLayout > ĊĠĠĠĠĠĠĠ Ġ</ layout > ĊĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠ Ġ) ĊĠĠĠ Ġassert Indexed Ids () ĊĠĠĠ Ġval Ġorientation Ġ= Ġfind Child Ġ{ ĊĠĠĠĠĠ Ġ( it Ġis ĠXml Attribute ) Ġ&& Ġit . local Name Ġ== Ġ" orientation " ĊĠĠĠ Ġ} !! ĊĠĠĠ Ġinsert Xml ( ĊĠĠĠĠĠ Ġoffset Ġ= Ġorientation . text Offset , ĊĠĠĠĠĠ Ġxml Ġ= Ġ""" android : id ="@ + id / root _ view " Ġ""" ĊĠĠĠ Ġ) ĊĠĠĠ Ġassert Indexed Ids ( ĊĠĠĠĠĠ ĠView Id Data (" root _ view ", Ġ" LinearLayout ", Ġnull ) ĊĠĠĠ Ġ) ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġ@ Runs In Ed t ĊĠ Ġfun Ġtest Remove Id From View () Ġ{ ĊĠĠĠ Ġsetup With Layout File ( ĊĠĠĠĠĠ Ġ""" ĊĠĠĠĠĠĠĠ Ġ< layout Ġxmlns : android =" http :// schemas . android . com / apk / res / android "> ĊĠĠĠĠĠĠĠĠĠ Ġ< LinearLayout ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : id ="@ + id / root _ view " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : orientation =" vertical " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : layout _ width =" fill _ parent " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : layout _ height =" fill _ parent "> ĊĠĠĠĠĠĠĠĠĠ Ġ</ LinearLayout > ĊĠĠĠĠĠĠĠ Ġ</ layout > ĊĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠ Ġ) ĊĠĠĠ Ġassert Indexed Ids ( ĊĠĠĠĠĠ ĠView Id Data (" root _ view ", Ġ" LinearLayout ", Ġnull ) ĊĠĠĠ Ġ) ĊĠĠĠ Ġval Ġid Attr Ġ= Ġfind Child Ġ{ ĊĠĠĠĠĠ Ġ( it Ġis ĠXml Attribute ) Ġ&& Ġit . local Name Ġ== Ġ" id " ĊĠĠĠ Ġ} !! ĊĠĠĠ Ġdelete Xml ( id Attr . text Range ) ĊĠĠĠ Ġassert Indexed Ids () ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġ@ Runs In Ed t ĊĠ Ġfun Ġtest Change Id () Ġ{ ĊĠĠĠ Ġsetup With Layout File ( ĊĠĠĠĠĠ Ġ""" ĊĠĠĠĠĠĠĠ Ġ< layout Ġxmlns : android =" http :// schemas . android . com / apk / res / android "> ĊĠĠĠĠĠĠĠĠĠ Ġ< LinearLayout ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : id ="@ + id / root _ view " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : orientation =" vertical " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : layout _ width =" fill _ parent " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : layout _ height =" fill _ parent "> ĊĠĠĠĠĠĠĠĠĠ Ġ</ LinearLayout > ĊĠĠĠĠĠĠĠ Ġ</ layout > ĊĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠ Ġ) ĊĠĠĠ Ġassert Indexed Ids ( ĊĠĠĠĠĠ ĠView Id Data (" root _ view ", Ġ" LinearLayout ", Ġnull ) ĊĠĠĠ Ġ) ĊĠĠĠ Ġval Ġid Attr Ġ= Ġfind Child Ġ{ ĊĠĠĠĠĠ Ġ( it Ġis ĠXml Attribute ) Ġ&& Ġit . local Name Ġ== Ġ" id " ĊĠĠĠ Ġ} !! ĊĠĠĠ Ġupdate Xml ( ĊĠĠĠĠĠ Ġrange Ġ= Ġ( id Attr Ġas ĠXml Attribute ). value Element !!. value Text Range , ĊĠĠĠĠĠ Ġxml Ġ= Ġ"@ + id / new _ id " ĊĠĠĠ Ġ) ĊĠĠĠ Ġassert Indexed Ids ( ĊĠĠĠĠĠ ĠView Id Data (" new _ id ", Ġ" LinearLayout ", Ġnull ) ĊĠĠĠ Ġ) ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġ@ Runs In Ed t ĊĠ Ġfun Ġtest Change ViewType () Ġ{ ĊĠĠĠ Ġsetup With Layout File ( ĊĠĠĠĠĠ Ġ""" ĊĠĠĠĠĠĠĠ Ġ< layout Ġxmlns : android =" http :// schemas . android . com / apk / res / android "> ĊĠĠĠĠĠĠĠĠĠ Ġ< LinearLayout ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : id ="@ + id / root _ view " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : orientation =" vertical " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : layout _ width =" fill _ parent " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : layout _ height =" fill _ parent "/> ĊĠĠĠĠĠĠĠ Ġ</ layout > ĊĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠ Ġ) ĊĠĠĠ Ġval Ġlinear Layout Ġ= Ġfind Child Ġ{ ĊĠĠĠĠĠ Ġ( it Ġis ĠXml Tag ) Ġ&& Ġit . local Name Ġ== Ġ" LinearLayout " ĊĠĠĠ Ġ} !! Ġas ĠXml Tag ĊĊĠĠĠ Ġupdate Xml ( ĊĠĠĠĠĠ Ġrange Ġ= ĠText Range ( linear Layout . start Offset In Parent , Ġlinear Layout . start Offset In Parent Ġ+ Ġ"< LinearLayout ". length ), ĊĠĠĠĠĠ Ġxml Ġ= Ġ"< TextView " ĊĠĠĠ Ġ) ĊĠĠĠ Ġassert Indexed Ids ( ĊĠĠĠĠĠ ĠView Id Data (" root _ view ", Ġ" TextView ", Ġnull ) ĊĠĠĠ Ġ) ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġ@ Runs In Ed t ĊĠ Ġfun Ġtest Add View With Id () Ġ{ ĊĠĠĠ Ġsetup With Layout File ( ĊĠĠĠĠĠ Ġ""" ĊĠĠĠĠĠĠĠ Ġ< layout Ġxmlns : android =" http :// schemas . android . com / apk / res / android "> ĊĠĠĠĠĠĠĠĠĠ Ġ< LinearLayout ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : id ="@ + id / root _ view " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : orientation =" vertical " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : layout _ width =" fill _ parent " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : layout _ height =" fill _ parent "> ĊĠĠĠĠĠĠĠĠĠ Ġ</ LinearLayout > ĊĠĠĠĠĠĠĠ Ġ</ layout > ĊĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠ Ġ) ĊĠĠĠ Ġassert Indexed Ids ( ĊĠĠĠĠĠ ĠView Id Data (" root _ view ", Ġ" LinearLayout ", Ġnull ) ĊĠĠĠ Ġ) ĊĠĠĠ Ġval Ġlinear Layout Ġ= Ġfind Child Ġ{ ĊĠĠĠĠĠ Ġ( it Ġis ĠXml Tag ) Ġ&& Ġit . local Name Ġ== Ġ" LinearLayout " ĊĠĠĠ Ġ} !! Ġas ĠXml Tag ĊĊĠĠĠ Ġinsert Xml ( ĊĠĠĠĠĠ Ġoffset Ġ= Ġlinear Layout . text Range . end Offset , ĊĠĠĠĠĠ Ġxml Ġ= Ġ""" ĊĠĠĠĠĠĠĠ Ġ< TextView ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : id ="@ + id / view 2 " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : layout _ width =" fill _ parent " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : layout _ height =" fill _ parent " ĊĠĠĠĠĠĠĠ Ġ/> ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠ Ġ) ĊĠĠĠ Ġassert Indexed Ids ( ĊĠĠĠĠĠ ĠView Id Data (" root _ view ", Ġ" LinearLayout ", Ġnull ), ĊĠĠĠĠĠ ĠView Id Data (" view 2 ", Ġ" TextView ", Ġnull ) ĊĠĠĠ Ġ) ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġ@ Runs In Ed t ĊĠ Ġfun Ġtest Un related Change _ attr () Ġ{ ĊĠĠĠ Ġsetup With Layout File ( ĊĠĠĠĠĠ Ġ""" ĊĠĠĠĠĠĠĠ Ġ< layout Ġxmlns : android =" http :// schemas . android . com / apk / res / android "> ĊĠĠĠĠĠĠĠĠĠ Ġ< LinearLayout ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : id ="@ + id / root _ view " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : orientation =" vertical " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : layout _ width =" fill _ parent " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : layout _ height =" fill _ parent "> ĊĠĠĠĠĠĠĠĠĠ Ġ</ LinearLayout > ĊĠĠĠĠĠĠĠ Ġ</ layout > ĊĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠ Ġ) ĊĠĠĠ Ġassert Indexed Ids ( ĊĠĠĠĠĠ ĠView Id Data (" root _ view ", Ġ" LinearLayout ", Ġnull ) ĊĠĠĠ Ġ) ĊĠĠĠ Ġval Ġorientation Attr Ġ= Ġfind Child Ġ{ ĊĠĠĠĠĠ Ġ( it Ġis ĠXml Attribute ) Ġ&& Ġit . local Name Ġ== Ġ" orientation " ĊĠĠĠ Ġ} !! ĊĠĠĠ Ġupdate Xml ( ĊĠĠĠĠĠ Ġrange Ġ= Ġ( orientation Attr Ġas ĠXml Attribute ). value Element !!. value Text Range , ĊĠĠĠĠĠ Ġxml Ġ= Ġ" horizontal " ĊĠĠĠ Ġ) ĊĠĠĠ Ġassert Indexed Ids ( ĊĠĠĠĠĠ ĠView Id Data (" root _ view ", Ġ" LinearLayout ", Ġnull ) ĊĠĠĠ Ġ) ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġ@ Runs In Ed t ĊĠ Ġfun Ġtest Un related Change _ addView () Ġ{ ĊĠĠĠ Ġsetup With Layout File ( ĊĠĠĠĠĠ Ġ""" ĊĠĠĠĠĠĠĠ Ġ< layout Ġxmlns : android =" http :// schemas . android . com / apk / res / android "> ĊĠĠĠĠĠĠĠĠĠ Ġ< LinearLayout ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : id ="@ + id / root _ view " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : orientation =" vertical " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : layout _ width =" fill _ parent " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : layout _ height =" fill _ parent "> ĊĠĠĠĠĠĠĠĠĠ Ġ</ LinearLayout > ĊĠĠĠĠĠĠĠ Ġ</ layout > ĊĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠ Ġ) ĊĠĠĠ Ġassert Indexed Ids ( ĊĠĠĠĠĠ ĠView Id Data (" root _ view ", Ġ" LinearLayout ", Ġnull ) ĊĠĠĠ Ġ) ĊĠĠĠ Ġval Ġlinear Layout Ġ= Ġfind Child Ġ{ ĊĠĠĠĠĠ Ġ( it Ġis ĠXml Tag ) Ġ&& Ġit . local Name Ġ== Ġ" LinearLayout " ĊĠĠĠ Ġ} !! Ġas ĠXml Tag ĊĊĠĠĠ Ġinsert Xml ( ĊĠĠĠĠĠ Ġoffset Ġ= Ġlinear Layout . text Range . end Offset , ĊĠĠĠĠĠ Ġxml Ġ= Ġ""" ĊĠĠĠĠĠĠĠ Ġ< TextView ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : layout _ width =" fill _ parent " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid : layout _ height =" fill _ parent " ĊĠĠĠĠĠĠĠ Ġ/> ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠ Ġ) ĊĠĠĠ Ġassert Indexed Ids ( ĊĠĠĠĠĠ ĠView Id Data (" root _ view ", Ġ" LinearLayout ", Ġnull ) ĊĠĠĠ Ġ) ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* Ġassert s Ġall Ġviews Ġwith Ġview Ids . ĊĠĠ Ġ* ĠPair s Ġare Ġvariable Ġname Ġto Ġview Ġtype ĊĠĠ Ġ*/ ĊĠ Ġprivate Ġfun Ġassert Indexed Ids ( var arg Ġexpected : ĠView Id Data ) Ġ{ ĊĠĠĠ Ġval Ġindexed Ids Ġ= ĠBinding Xml Index . getData For File ( psi File ) !!. view Ids . toSet () ĊĠĠĠ ĠassertThat ( indexed Ids ). isEqualTo ( expected . toSet ()) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġsetup With Layout File ( layout Contents : ĠString ) Ġ{ ĊĠĠĠ Ġpsi File Ġ= Ġfixture . add File To Project (" res / layout / test _ layout . xml ", Ġlayout Contents ) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġfind Child ( predicate : Ġ( Psi Element ) Ġ-> ĠBoolean ): ĠPsi Element ? Ġ{ ĊĠĠĠ Ġreturn ĠSyntax Tra verser . psi Tra verser ( psi File ). traverse (). filter ( predicate ). first OrNull () ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġinsert Xml ( offset : ĠInt , Ġxml : ĠString ) Ġ{ ĊĠĠĠ Ġval Ġdocument Manager Ġ= ĠPsi Document Manager . getInstance ( project ) ĊĠĠĠ Ġval Ġdocument Ġ= Ġdocument Manager . getDocument ( psi File ) !! ĊĠĠĠ ĠWrite Command Action . run Write Command Action ( project ) Ġ{ ĊĠĠĠĠĠ Ġdocument . insert String ( offset , Ġxml ) ĊĠĠĠĠĠ Ġdocument Manager . commit Document ( document ) ĊĠĠĠ Ġ} ĊĠĠĠ ĠUI Util . dispatch All Invocation Events () ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġupdate Xml ( range : ĠText Range , Ġxml : ĠString ) Ġ{ ĊĠĠĠ Ġval Ġdocument Manager Ġ= ĠPsi Document Manager . getInstance ( project ) ĊĠĠĠ Ġval Ġdocument Ġ= Ġdocument Manager . getDocument ( psi File ) !! ĊĠĠĠ ĠWrite Command Action . run Write Command Action ( project ) Ġ{ ĊĠĠĠĠĠ Ġdocument . replace String ( range . start Offset , Ġrange . end Offset , Ġxml ) ĊĠĠĠĠĠ Ġdocument Manager . commit Document ( document ) ĊĠĠĠ Ġ} ĊĠĠĠ ĠUI Util . dispatch All Invocation Events () ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġdelete Xml ( range : ĠText Range ) Ġ{ ĊĠĠĠ Ġval Ġdocument Manager Ġ= ĠPsi Document Manager . getInstance ( project ) ĊĠĠĠ Ġval Ġdocument Ġ= Ġdocument Manager . getDocument ( psi File ) !! ĊĠĠĠ ĠWrite Command Action . run Write Command Action ( project ) Ġ{ ĊĠĠĠĠĠ Ġdocument . delete String ( range . start Offset , Ġrange . end Offset ) ĊĠĠĠĠĠ Ġdocument Manager . commit Document ( document ) ĊĠĠĠ Ġ} ĊĠĠĠ ĠUI Util . dispatch All Invocation Events () ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġverify Serialization Logic ( value External izer : ĠData External izer < Binding Xml Data >, Ġdata : ĠBinding Xml Data ) Ġ{ ĊĠĠĠ Ġval Ġbytes Out Ġ= ĠByteArrayOutputStream () ĊĠĠĠ ĠData OutputStream ( bytes Out ). use Ġ{ Ġvalue External izer . save ( it , Ġdata ) Ġ} ĊĊĠĠĠ Ġval Ġbytes In Ġ= ĠByteArrayInputStream ( bytes Out . toByteArray ()) ĊĠĠĠ Ġval Ġdata Copy Ġ= ĠData InputStream ( bytes In ). use Ġ{ Ġvalue External izer . read ( it ) Ġ} ĊĠĠĠ ĠassertThat ( data Copy ). isEqualTo ( data ) ĊĠ Ġ} Ċ }