package Ġtesting Ċ Ċ import Ġgro ovy . util . Node Ċ import Ġjava . io . File Ċ import Ġutil . forEach File Ċ import Ġutil . forEach Node Ċ import Ġutil . parse Xml Ċ Ċ private Ġfun Ġget Xml s TestResult Dirs ( files : ĠIterable < File >): ĠList < File > Ġ{ ĊĠĠĠ Ġval Ġresult Ġ= Ġmutable ListOf < File >() ĊĠĠĠ Ġval Ġend sWith Binary Ġ= Ġ"/ binary " ĊĠĠĠ Ġfiles . forEach Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( it . absolute Path . endsWith ( endsWith Binary )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġabsolute Path Ġ= Ġit . absolute Path ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpath Ġ= Ġabsolute Path . substring ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠstartIndex Ġ= Ġ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġend Index Ġ= Ġabsolute Path . length Ġ- Ġend sWith Binary . length ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFile ( path ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( exists ()) ĠforEach File Ġ{ Ġfile Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( file . name . endsWith (". xml ")) Ġresult . add ( file ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġresult Ċ } Ċ Ċ private Ġval Ġallowed Keys Ġ= Ġset Of (" name ", Ġ" tests ", Ġ" skipped ", Ġ" failures ", Ġ" errors ") Ċ private Ġval Ġallowed Names Ġ= Ġset Of (" testcase ") Ċ private Ġval Ġallowed TestCase Keys Ġ= Ġset Of (" name ", Ġ" classname ") Ċ private Ġval Ġallowed TestCase Names Ġ= Ġset Of (" failure ") Ċ fun Ġget Testing Signature ( files : ĠIterable < File >): ĠString Ġ{ ĊĠĠĠ Ġreturn Ġget Xml s TestResult Dirs ( files ). sorted By Ġ{ Ġit . absolute Path Ġ}. fold ("") Ġ{ Ġaccumulator , Ġfile Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġroot Ġ= Ġparse Xml ( file . read Text ()) ĊĠĠĠĠĠĠĠ Ġroot . attributes (). also Ġ{ Ġattributes Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġattributes . keys . toList (). forEach Ġ{ Ġkey Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( key Ġ! in Ġallowed Keys ) Ġattributes . remove ( key ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġroot . children (). also Ġ{ Ġchildren Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchildren . toList (). forEach Ġ{ Ġchild Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchild Ġas ? ĠNode Ġ?: Ġthrow ĠIllegalStateException () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( child . name () Ġ! in Ġallowed Names ) Ġchildren . remove ( child ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġroot . forEach Node (" testcase ") Ġ{ Ġnode Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnode . attributes (). also Ġ{ Ġattributes Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġattributes . keys . toList (). forEach Ġ{ Ġkey Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( key Ġ! in Ġallowed TestCase Keys ) Ġattributes . remove ( key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnode . children (). also Ġ{ Ġchildren Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchildren . toList (). forEach Ġ{ Ġchild Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchild Ġas ? ĠNode Ġ?: Ġthrow ĠIllegalStateException () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( child . name () Ġ! in Ġallowed TestCase Names ) Ġchildren . remove ( child ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnode . forEach Node (" failure ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . setValue ( Node ( node , Ġ"")) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġaccumulator Ġ+ Ġroot . signature Recur se () ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠNode . signature Recur se (): ĠString Ġ{ ĊĠĠĠ Ġvar Ġresult Ġ= Ġname (). toString () ĊĠĠĠ Ġresult Ġ+= Ġattributes (). toList (). sorted By Ġ{ Ġ( key , Ġ_) Ġ-> Ġkey . toString () Ġ}. fold ("") Ġ{ Ġsignature , Ġ( key , Ġvalue ) Ġ-> ĊĠĠĠĠĠĠĠ Ġsignature Ġ+ Ġ"_" Ġ+ Ġkey . toString () Ġ+ Ġvalue . toString () ĊĠĠĠ Ġ} ĊĠĠĠ Ġchildren (). map Ġ{ ĊĠĠĠĠĠĠĠ Ġit Ġas ? ĠNode Ġ?: Ġthrow ĠIllegalStateException (" child Ġof Ġ$ this Ġmust Ġbe Ġgro ovy . util . Node ") ĊĠĠĠ Ġ}. sorted By Ġ{ Ġit . name (). toString () Ġ}. forEach Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( it . attributes (). isNotEmpty () Ġ|| Ġit . children (). isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ+= Ġ"_" Ġ+ Ġit . signature Recur se () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġresult Ċ } Ċ