import Ġorg . junit . Test Ċ import Ġse . ek bl ad . k sv . Csv Key Ċ import Ġse . ek bl ad . k sv . Csv Parser Ċ import Ġse . ek bl ad . k sv . Csv Parser Defaults Ċ import Ġjava . time .* Ċ import Ġkotlin . reflect . full . create Type Ċ import Ġkotlin . test . assertEquals Ċ import Ġkotlin . test . assert Fails With Ċ import Ġkotlin . test . assertTrue Ċ Ċ class ĠCsv Parser Test Ġ{ ĊĠĠĠ Ġprivate Ġval Ġs sv Ġ= Ġ""" ĊĠĠĠĠĠĠĠ Ġplain ; with Ġspaces ;' quoted ; separator ' ĊĠĠĠĠĠĠĠ Ġ' hello ; world '; ĠĠ Ġ" 1 2 3 " Ġ; Ġ 1 . 2 3 ĊĠĠĠĠĠĠĠ Ġtrue ; 4 5 6 ; 1 e 1 0 ĊĠĠĠ Ġ""" . trim Indent () ĊĊĠĠĠ Ġprivate Ġval Ġs sv Rows Ġ= ĠlistOf ( ĊĠĠĠĠĠĠĠ Ġmap Of (" plain " Ġto Ġ" hello ; world ", Ġ" with Ġspaces " Ġto Ġ" 1 2 3 ", Ġ" quoted ; separator " Ġto Ġ" 1 . 2 3 "), ĊĠĠĠĠĠĠĠ Ġmap Of (" plain " Ġto Ġ" true ", Ġ" with Ġspaces " Ġto Ġ" 4 5 6 ", Ġ" quoted ; separator " Ġto Ġ" 1 e 1 0 ") ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` parser Ġcan Ġparse Ġstring Ġregardless Ġof Ġseparator `() Ġ{ ĊĠĠĠĠĠĠĠ ĠlistOf (',', Ġ'\ t ', Ġ'; ', Ġ'\ u 0 0 0 0 ', Ġ' è© ¦ '). forEach Ġ{ Ġseparator Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrows Ġ= ĠCsv Parser Ġ{ Ġsepar ators Ġ= ĠlistOf ( separator ) Ġ}. read Csv Rows ( ss v . replace (' ;', Ġseparator )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Rows Ġ= Ġs sv Rows . map Ġ{ Ġrow Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrow . map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . key . replace (' ;', Ġseparator ) Ġto Ġit . value . replace (' ;', Ġseparator ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. toMap () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( expected Rows , Ġrows ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` parser Ġignores Ġleading Ġwhitespace `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġrow Ġ= ĠCsv Parser . csv . read Csv Rows ("\ n \ n \ n ĠĠĠĠ Ġhello \ n \ tw orld "). single () ĊĠĠĠĠĠĠĠ ĠassertEquals ( map Of (" hello " Ġto Ġ" world "), Ġrow ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` parser Ġignores Ġtrailing Ġwhitespace `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġrow Ġ= ĠCsv Parser . csv . read Csv Rows (" hello ĠĠĠ Ġ\ t \ t Ġ\ n \ tw orld \ t \ t ĠĠ Ġ\ n \ n \ n ĠĠ Ġ"). single () ĊĠĠĠĠĠĠĠ ĠassertEquals ( map Of (" hello " Ġto Ġ" world "), Ġrow ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` can Ġconvert Ġall Ġbuilt - in Ġtypes `() Ġ{ ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠFoo ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġa : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġb : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġc : ĠDouble , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġd : ĠBoolean , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġe : ĠOffset DateTime , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġf : ĠOffset Time , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġg : ĠLocalDateTime , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġh : ĠLocalDate , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġi : ĠLocal Time ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġval Ġcsv Ġ= Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġa , b , c , d , e , f , g , h , i ĊĠĠĠĠĠĠĠĠĠĠĠĠ 1 , xyz , 1 e 1 0 , yes , 2 0 2 1 - 0 1 - 0 2 T 0 3 : 0 4 : 0 0 . 0 + 0 1 : 0 0 , 0 1 : 0 2 Z , 2 0 2 1 - 0 2 - 0 3 T 0 4 : 0 5 , 2 0 2 1 - 0 3 - 0 4 , 0 6 : 0 7 ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠĠĠĠĠ Ġval Ġfoo Ġ= ĠCsv Parser . csv . read Csv < Foo >( csv ). single () ĊĠĠĠĠĠĠĠ Ġval Ġexpected Foo Ġ= ĠFoo ( ĊĠĠĠĠĠĠĠĠĠĠĠĠ 1 , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" xyz ", ĊĠĠĠĠĠĠĠĠĠĠĠĠ 1 e 1 0 , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtrue , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOffset DateTime . of ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLocalDateTime . of ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLocalDate . of ( 2 0 2 1 , Ġ 1 , Ġ 2 ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLocal Time . of ( 3 , Ġ 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠZone Offset . of Hours ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOffset Time . of ( Local Time . of ( 1 , Ġ 2 ), ĠZone Offset . UTC ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLocalDateTime . of ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLocalDate . of ( 2 0 2 1 , Ġ 2 , Ġ 3 ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLocal Time . of ( 4 , Ġ 5 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLocalDate . of ( 2 0 2 1 , Ġ 3 , Ġ 4 ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLocal Time . of ( 6 , Ġ 7 ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( expected Foo , Ġfoo ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` can Ġparse Ġdata Ġclass Ġeven Ġif Ġfield Ġorder Ġdoes Ġnot Ġmatch Ġup Ġwith Ġcolumn Ġorder `() Ġ{ ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠFoo ( val Ġa : ĠInt , Ġval Ġb : ĠString ) ĊĠĠĠĠĠĠĠ Ġval Ġcsv Ġ= Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġb , a ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhello , 1 2 3 ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĊĠĠĠĠĠĠĠ Ġval Ġexpected Foo Ġ= ĠFoo ( 1 2 3 , Ġ" hello ") ĊĠĠĠĠĠĠĠ Ġval Ġfoo Ġ= ĠCsv Parser . csv . read Csv < Foo >( csv ). single () ĊĠĠĠĠĠĠĠ ĠassertEquals ( expected Foo , Ġfoo ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` can Ġparse Ġdata Ġclass Ġwith Ġannotated Ġfields `() Ġ{ ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠFoo (@ Csv Key (" b ") Ġval Ġa : ĠInt , Ġ@ Csv Key (" a ") Ġval Ġb : ĠString , Ġval Ġc : ĠBoolean ) ĊĠĠĠĠĠĠĠ Ġval Ġcsv Ġ= Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġa , b , c ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhello , 1 2 3 , y ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĊĠĠĠĠĠĠĠ Ġval Ġexpected Foo Ġ= ĠFoo ( 1 2 3 , Ġ" hello ", Ġtrue ) ĊĠĠĠĠĠĠĠ Ġval Ġfoo Ġ= ĠCsv Parser . csv . read Csv < Foo >( csv ). single () ĊĠĠĠĠĠĠĠ ĠassertEquals ( expected Foo , Ġfoo ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` unknown Ġcolumns Ġare Ġnot Ġallowed Ġby Ġdefault `() Ġ{ ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠFoo ( val Ġa : ĠString ) ĊĠĠĠĠĠĠĠ Ġval Ġcsv Ġ= Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġa , b ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhello , 1 2 3 ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĊĠĠĠĠĠĠĠ Ġassert Fails With < IllegalArgumentException > Ġ{ ĠCsv Parser . csv . read Csv < Foo >( csv ). single () Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` unknown Ġcolumns Ġare Ġallowed Ġwith Ġthe Ġcorrect Ġoption `() Ġ{ ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠFoo ( val Ġa : ĠString ) ĊĠĠĠĠĠĠĠ Ġval Ġcsv Ġ= Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġa , b ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhello , 1 2 3 ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĊĠĠĠĠĠĠĠ Ġval Ġexpected Foo Ġ= ĠFoo (" hello ") ĊĠĠĠĠĠĠĠ Ġval Ġfoo Ġ= ĠCsv Parser . csv . with Ġ{ Ġignore Unknown Columns Ġ= Ġtrue Ġ}. read Csv < Foo >( csv ). single () ĊĠĠĠĠĠĠĠ ĠassertEquals ( expected Foo , Ġfoo ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` all Ġfields Ġof Ġparsed Ġtype Ġmust Ġmap Ġto Ġcolumns `() Ġ{ ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠFoo ( val Ġa : ĠString , Ġval Ġb : ĠInt ) ĊĊĠĠĠĠĠĠĠ Ġassert Fails With < IllegalArgumentException > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCsv Parser . csv . read Csv < Foo >(" a \ n hello "). single () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġassert Fails With < IllegalArgumentException > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCsv Parser . csv . read Csv < Foo >(" a , b \ n hello , world "). single () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ`' with ' Ġdoes Ġnot Ġmutate Ġits Ġreceiver `() Ġ{ ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠFoo ( val Ġa : ĠString ) ĊĠĠĠĠĠĠĠ Ġval Ġcsv Ġ= Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġa , b ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhello , world ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĊĠĠĠĠĠĠĠ Ġval Ġoriginal Parser Ġ= ĠCsv Parser Ġ{ Ġignore Unknown Columns Ġ= Ġfalse Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġnew Parser Ġ= Ġoriginal Parser . with Ġ{ Ġignore Unknown Columns Ġ= Ġtrue Ġ} ĊĊĠĠĠĠĠĠĠ Ġassert Fails With < IllegalArgumentException > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoriginal Parser . read Csv < Foo >( csv ). single () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ ĠassertEquals ( Foo (" hello "), Ġnew Parser . read Csv < Foo >( csv ). single ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` can Ġconfigure Ġquote Ġchars `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcsv Ġ= Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ| a | ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ' hello ' ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĊĠĠĠĠĠĠĠ Ġval Ġrow Ġ= ĠCsv Parser . csv . with Ġ{ Ġquotes Ġ= ĠlistOf ('| ') Ġ}. read Csv Rows ( csv ). single () ĊĠĠĠĠĠĠĠ Ġval Ġexpected Row Ġ= Ġmap Of (" a " Ġto Ġ"' hello '") ĊĠĠĠĠĠĠĠ ĠassertEquals ( expected Row , Ġrow ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` can Ġadd Ġnew Ġtype Ġconverter s , Ġwithout Ġaffect ing Ġoriginal Ġparser `() Ġ{ ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠRe versed ( val Ġstring : ĠString ) ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠFoo ( val Ġa : ĠRe versed ) ĊĠĠĠĠĠĠĠ Ġval Ġcsv Ġ= Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġa ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhello ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĊĠĠĠĠĠĠĠ Ġval Ġoriginal Parser Ġ= ĠCsv Parser () ĊĠĠĠĠĠĠĠ Ġval Ġnew Parser Ġ= Ġoriginal Parser . with Ġ{ Ġtype Converters Ġ+= Ġ{ ĠRe versed ( it . reversed ()) Ġ} Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġfoo Ġ= Ġnew Parser . read Csv < Foo >( csv ). single () ĊĠĠĠĠĠĠĠ Ġval Ġexpected Foo Ġ= ĠFoo ( Re versed (" ol le h ")) ĊĠĠĠĠĠĠĠ ĠassertEquals ( expected Foo , Ġfoo ) ĊĠĠĠĠĠĠĠĠĊĠĠĠĠĠĠĠ Ġassert Fails With < IllegalArgumentException > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoriginal Parser . read Csv < Foo >( csv ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` parser Ġfails Ġon Ġmis matched Ġquote Ġchars `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcsv Ġ= Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" a ' ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhello ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠĠĠĠĠ Ġassert Fails With < IllegalArgumentException > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCsv Parser . csv . read Csv Rows ( csv ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` parser Ġfails Ġon Ġgarbage Ġbetween Ġquoted Ġvalues `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcsv Ġ= Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ' a ' Ġgarbage , Ġ' b ' ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhello , world ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠĠĠĠĠ Ġassert Fails With < IllegalArgumentException > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCsv Parser . csv . read Csv Rows ( csv ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` parser Ġfails Ġon Ġmissing Ġend Ġquote `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcsv Ġ= Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ' a ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhello ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠĠĠĠĠ Ġassert Fails With < IllegalArgumentException > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCsv Parser . csv . read Csv Rows ( csv ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` quote Ġchars Ġcan Ġbe Ġescaped `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcsv Ġ= Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ'\' a \ '' ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhello ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= ĠCsv Parser . csv . read Csv Rows ( csv ). single (). keys . single () ĊĠĠĠĠĠĠĠ ĠassertEquals ("' a '", Ġkey ) ĊĠĠĠ Ġ} ĊĠĠĠĠĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` separator Ġchars Ġcan Ġbe Ġescaped `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcsv Ġ= Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ\ ,\ ,\ , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhello ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= ĠCsv Parser . csv . read Csv Rows ( csv ). single (). keys . single () ĊĠĠĠĠĠĠĠ ĠassertEquals (", ,, ", Ġkey ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` escape Ġchar Ġcan Ġbe Ġescaped `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcsv Ġ= Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ\\ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhello ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= ĠCsv Parser . csv . read Csv Rows ( csv ). single (). keys . single () ĊĠĠĠĠĠĠĠ ĠassertEquals ("\\ ", Ġkey ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` one Ġquote Ġchar Ġcan Ġappear Ġun escaped Ġbetween Ġtwo Ġother Ġquote Ġchars `() Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcsv Ġ= Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ'" a "' ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhello ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= ĠCsv Parser . csv . read Csv Rows ( csv ). single (). keys . single () ĊĠĠĠĠĠĠĠ ĠassertEquals ("\" a \"", Ġkey ) ĊĠĠĠ Ġ} Ċ } Ċ