TextFormatterTests.cs 209 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291
  1. using System.Text;
  2. using Xunit.Abstractions;
  3. // Alias Console to MockConsole so we don't accidentally use Console
  4. namespace Terminal.Gui.TextTests;
  5. public class TextFormatterTests
  6. {
  7. private readonly ITestOutputHelper _output;
  8. public TextFormatterTests (ITestOutputHelper output) { _output = output; }
  9. public static IEnumerable<object []> CMGlyphs =>
  10. new List<object []> { new object [] { $"{CM.Glyphs.LeftBracket} Say Hello 你 {CM.Glyphs.RightBracket}", 16, 15 } };
  11. public static IEnumerable<object []> FormatEnvironmentNewLine =>
  12. new List<object []>
  13. {
  14. new object []
  15. {
  16. $"Line1{Environment.NewLine}Line2{Environment.NewLine}Line3{Environment.NewLine}",
  17. 60,
  18. new [] { "Line1", "Line2", "Line3" }
  19. }
  20. };
  21. public static IEnumerable<object []> SplitEnvironmentNewLine =>
  22. new List<object []>
  23. {
  24. new object []
  25. {
  26. $"First Line 界{Environment.NewLine}Second Line 界{Environment.NewLine}Third Line 界",
  27. new [] { "First Line 界", "Second Line 界", "Third Line 界" }
  28. },
  29. new object []
  30. {
  31. $"First Line 界{Environment.NewLine}Second Line 界{Environment.NewLine}Third Line 界{Environment.NewLine}",
  32. new [] { "First Line 界", "Second Line 界", "Third Line 界", "" }
  33. }
  34. };
  35. [Theory]
  36. [InlineData (null)]
  37. [InlineData ("")]
  38. public void CalcRect_Invalid_Returns_Empty (string text)
  39. {
  40. Assert.Equal (Rectangle.Empty, TextFormatter.CalcRect (0, 0, text));
  41. Assert.Equal (new (new (1, 2), Size.Empty), TextFormatter.CalcRect (1, 2, text));
  42. Assert.Equal (new (new (-1, -2), Size.Empty), TextFormatter.CalcRect (-1, -2, text));
  43. }
  44. [Theory]
  45. [InlineData ("line1\nline2", 5, 2)]
  46. [InlineData ("\nline2", 5, 2)]
  47. [InlineData ("\n\n", 0, 3)]
  48. [InlineData ("\n\n\n", 0, 4)]
  49. [InlineData ("line1\nline2\nline3long!", 10, 3)]
  50. [InlineData ("line1\nline2\n\n", 5, 4)]
  51. [InlineData ("line1\r\nline2", 5, 2)]
  52. [InlineData (" ~  s  gui.cs   master ↑10\n", 31, 2)]
  53. [InlineData ("\n ~  s  gui.cs   master ↑10", 31, 2)]
  54. [InlineData (" ~  s  gui.cs   master\n↑10", 27, 2)]
  55. public void CalcRect_MultiLine_Returns_nHigh (string text, int expectedWidth, int expectedLines)
  56. {
  57. Assert.Equal (new (0, 0, expectedWidth, expectedLines), TextFormatter.CalcRect (0, 0, text));
  58. string [] lines = text.Split (text.Contains (Environment.NewLine) ? Environment.NewLine : "\n");
  59. int maxWidth = lines.Max (s => s.GetColumns ());
  60. var lineWider = 0;
  61. for (var i = 0; i < lines.Length; i++)
  62. {
  63. int w = lines [i].GetColumns ();
  64. if (w == maxWidth)
  65. {
  66. lineWider = i;
  67. }
  68. }
  69. Assert.Equal (new (0, 0, maxWidth, expectedLines), TextFormatter.CalcRect (0, 0, text));
  70. Assert.Equal (
  71. new (
  72. 0,
  73. 0,
  74. lines [lineWider].ToRuneList ().Sum (r => Math.Max (r.GetColumns (), 0)),
  75. expectedLines
  76. ),
  77. TextFormatter.CalcRect (0, 0, text)
  78. );
  79. }
  80. [Theory]
  81. [InlineData ("test")]
  82. [InlineData (" ~  s  gui.cs   master ↑10")]
  83. public void CalcRect_SingleLine_Returns_1High (string text)
  84. {
  85. Assert.Equal (new (0, 0, text.GetRuneCount (), 1), TextFormatter.CalcRect (0, 0, text));
  86. Assert.Equal (new (0, 0, text.GetColumns (), 1), TextFormatter.CalcRect (0, 0, text));
  87. }
  88. [Theory]
  89. [InlineData (14, 1, TextDirection.LeftRight_TopBottom)]
  90. [InlineData (1, 14, TextDirection.TopBottom_LeftRight)]
  91. public void CalcRect_With_Combining_Runes (int width, int height, TextDirection textDirection)
  92. {
  93. var text = "Les Mise\u0328\u0301rables";
  94. Assert.Equal (new (0, 0, width, height), TextFormatter.CalcRect (0, 0, text, textDirection));
  95. }
  96. [Theory]
  97. [InlineData ("test", TextDirection.LeftRight_TopBottom)]
  98. [InlineData (" ~  s  gui.cs   master ↑10", TextDirection.LeftRight_TopBottom)]
  99. [InlineData ("Say Hello view4 你", TextDirection.LeftRight_TopBottom)]
  100. [InlineData ("Say Hello view4 你", TextDirection.RightLeft_TopBottom)]
  101. [InlineData ("Say Hello view4 你", TextDirection.LeftRight_BottomTop)]
  102. [InlineData ("Say Hello view4 你", TextDirection.RightLeft_BottomTop)]
  103. public void CalcRect_Horizontal_Width_Correct (string text, TextDirection textDirection)
  104. {
  105. // The width is the number of columns in the text
  106. Assert.Equal (new (text.GetColumns (), 1), TextFormatter.CalcRect (0, 0, text, textDirection).Size);
  107. }
  108. [Theory]
  109. [InlineData ("test", TextDirection.TopBottom_LeftRight)]
  110. [InlineData (" ~  s  gui.cs   master ↑10", TextDirection.TopBottom_LeftRight)]
  111. [InlineData ("Say Hello view4 你", TextDirection.TopBottom_LeftRight)]
  112. [InlineData ("Say Hello view4 你", TextDirection.TopBottom_RightLeft)]
  113. [InlineData ("Say Hello view4 你", TextDirection.BottomTop_LeftRight)]
  114. [InlineData ("Say Hello view4 你", TextDirection.BottomTop_RightLeft)]
  115. public void CalcRect_Vertical_Height_Correct (string text, TextDirection textDirection)
  116. {
  117. // The height is based both the number of lines and the number of wide chars
  118. Assert.Equal (new (1 + text.GetColumns () - text.Length, text.Length), TextFormatter.CalcRect (0, 0, text, textDirection).Size);
  119. }
  120. [Theory]
  121. [InlineData ("")]
  122. [InlineData (null)]
  123. [InlineData ("test")]
  124. public void ClipAndJustify_Invalid_Returns_Original (string text)
  125. {
  126. string expected = string.IsNullOrEmpty (text) ? text : "";
  127. Assert.Equal (expected, TextFormatter.ClipAndJustify (text, 0, Alignment.Start));
  128. Assert.Equal (expected, TextFormatter.ClipAndJustify (text, 0, Alignment.Start));
  129. Assert.Throws<ArgumentOutOfRangeException> (
  130. () =>
  131. TextFormatter.ClipAndJustify (text, -1, Alignment.Start)
  132. );
  133. }
  134. [Theory]
  135. [InlineData ("test", "", 0)]
  136. [InlineData ("test", "te", 2)]
  137. [InlineData ("test", "test", int.MaxValue)]
  138. [InlineData ("A sentence has words.", "A sentence has words.", 22)] // should fit
  139. [InlineData ("A sentence has words.", "A sentence has words.", 21)] // should fit
  140. [InlineData ("A sentence has words.", "A sentence has words.", int.MaxValue)] // should fit
  141. [InlineData ("A sentence has words.", "A sentence has words", 20)] // Should not fit
  142. [InlineData ("A sentence has words.", "A sentence", 10)] // Should not fit
  143. [InlineData ("A\tsentence\thas\twords.", "A sentence has words.", int.MaxValue)]
  144. [InlineData ("A\tsentence\thas\twords.", "A sentence", 10)]
  145. [InlineData ("line1\nline2\nline3long!", "line1\nline2\nline3long!", int.MaxValue)]
  146. [InlineData ("line1\nline2\nline3long!", "line1\nline", 10)]
  147. [InlineData (" ~  s  gui.cs   master ↑10", " ~  s  ", 10)] // Unicode
  148. [InlineData ("Ð ÑÐ", "Ð ÑÐ", 5)] // should fit
  149. [InlineData ("Ð ÑÐ", "Ð ÑÐ", 4)] // should fit
  150. [InlineData ("Ð ÑÐ", "Ð Ñ", 3)] // Should not fit
  151. public void ClipAndJustify_Valid_Centered (string text, string justifiedText, int maxWidth)
  152. {
  153. var alignment = Alignment.Center;
  154. var textDirection = TextDirection.LeftRight_TopBottom;
  155. var tabWidth = 1;
  156. Assert.Equal (
  157. justifiedText,
  158. TextFormatter.ClipAndJustify (text, maxWidth, alignment, textDirection, tabWidth)
  159. );
  160. int expectedClippedWidth = Math.Min (justifiedText.GetRuneCount (), maxWidth);
  161. Assert.Equal (
  162. justifiedText,
  163. TextFormatter.ClipAndJustify (text, maxWidth, alignment, textDirection, tabWidth)
  164. );
  165. Assert.True (justifiedText.GetRuneCount () <= maxWidth);
  166. Assert.True (justifiedText.GetColumns () <= maxWidth);
  167. Assert.Equal (expectedClippedWidth, justifiedText.GetRuneCount ());
  168. Assert.Equal (
  169. expectedClippedWidth,
  170. justifiedText.ToRuneList ().Sum (r => Math.Max (r.GetColumns (), 1))
  171. );
  172. Assert.True (expectedClippedWidth <= maxWidth);
  173. Assert.Equal (
  174. StringExtensions.ToString (justifiedText.ToRunes () [..expectedClippedWidth]),
  175. justifiedText
  176. );
  177. }
  178. [Theory]
  179. [InlineData ("test", "", 0)]
  180. [InlineData ("test", "te", 2)]
  181. [InlineData ("test", "test", int.MaxValue)] // This doesn't throw because it only create a word with length 1
  182. [InlineData ("A sentence has words.", "A sentence has words.", 22)] // should fit
  183. [InlineData ("A sentence has words.", "A sentence has words.", 21)] // should fit
  184. [InlineData (
  185. "A sentence has words.",
  186. "A sentence has words.",
  187. 500
  188. )] // should fit
  189. [InlineData ("A sentence has words.", "A sentence has words", 20)] // Should not fit
  190. [InlineData ("A sentence has words.", "A sentence", 10)] // Should not fit
  191. // Now throw System.OutOfMemoryException. See https://stackoverflow.com/questions/20672920/maxcapacity-of-stringbuilder
  192. //[InlineData ("A\tsentence\thas\twords.", "A sentence has words.", int.MaxValue)]
  193. [InlineData ("A\tsentence\thas\twords.", "A sentence", 10)]
  194. [InlineData (
  195. "line1\nline2\nline3long!",
  196. "line1\nline2\nline3long!",
  197. int.MaxValue
  198. )] // This doesn't throw because it only create a line with length 1
  199. [InlineData ("line1\nline2\nline3long!", "line1\nline", 10)]
  200. [InlineData (" ~  s  gui.cs   master ↑10", " ~  s  ", 10)] // Unicode
  201. [InlineData ("Ð ÑÐ", "Ð ÑÐ", 5)] // should fit
  202. [InlineData ("Ð ÑÐ", "Ð ÑÐ", 4)] // should fit
  203. [InlineData ("Ð ÑÐ", "Ð Ñ", 3)] // Should not fit
  204. public void ClipAndJustify_Valid_Justified (string text, string justifiedText, int maxWidth)
  205. {
  206. var alignment = Alignment.Fill;
  207. var textDirection = TextDirection.LeftRight_TopBottom;
  208. var tabWidth = 1;
  209. Assert.Equal (
  210. justifiedText,
  211. TextFormatter.ClipAndJustify (text, maxWidth, alignment, textDirection, tabWidth)
  212. );
  213. int expectedClippedWidth = Math.Min (justifiedText.GetRuneCount (), maxWidth);
  214. Assert.Equal (
  215. justifiedText,
  216. TextFormatter.ClipAndJustify (text, maxWidth, alignment, textDirection, tabWidth)
  217. );
  218. Assert.True (justifiedText.GetRuneCount () <= maxWidth);
  219. Assert.True (justifiedText.GetColumns () <= maxWidth);
  220. Assert.Equal (expectedClippedWidth, justifiedText.GetRuneCount ());
  221. Assert.Equal (
  222. expectedClippedWidth,
  223. justifiedText.ToRuneList ().Sum (r => Math.Max (r.GetColumns (), 1))
  224. );
  225. Assert.True (expectedClippedWidth <= maxWidth);
  226. Assert.Equal (
  227. StringExtensions.ToString (justifiedText.ToRunes () [..expectedClippedWidth]),
  228. justifiedText
  229. );
  230. // see Justify_ tests below
  231. }
  232. [Theory]
  233. [InlineData ("test", "", 0)]
  234. [InlineData ("test", "te", 2)]
  235. [InlineData ("test", "test", int.MaxValue)]
  236. [InlineData ("A sentence has words.", "A sentence has words.", 22)] // should fit
  237. [InlineData ("A sentence has words.", "A sentence has words.", 21)] // should fit
  238. [InlineData ("A sentence has words.", "A sentence has words.", int.MaxValue)] // should fit
  239. [InlineData ("A sentence has words.", "A sentence has words", 20)] // Should not fit
  240. [InlineData ("A sentence has words.", "A sentence", 10)] // Should not fit
  241. [InlineData ("A\tsentence\thas\twords.", "A sentence has words.", int.MaxValue)]
  242. [InlineData ("A\tsentence\thas\twords.", "A sentence", 10)]
  243. [InlineData ("line1\nline2\nline3long!", "line1\nline2\nline3long!", int.MaxValue)]
  244. [InlineData ("line1\nline2\nline3long!", "line1\nline", 10)]
  245. [InlineData (" ~  s  gui.cs   master ↑10", " ~  s  ", 10)] // Unicode
  246. [InlineData ("Ð ÑÐ", "Ð ÑÐ", 5)] // should fit
  247. [InlineData ("Ð ÑÐ", "Ð ÑÐ", 4)] // should fit
  248. [InlineData ("Ð ÑÐ", "Ð Ñ", 3)] // Should not fit
  249. public void ClipAndJustify_Valid_Left (string text, string justifiedText, int maxWidth)
  250. {
  251. var alignment = Alignment.Start;
  252. var textDirection = TextDirection.LeftRight_BottomTop;
  253. var tabWidth = 1;
  254. Assert.Equal (
  255. justifiedText,
  256. TextFormatter.ClipAndJustify (text, maxWidth, alignment, textDirection, tabWidth)
  257. );
  258. int expectedClippedWidth = Math.Min (justifiedText.GetRuneCount (), maxWidth);
  259. Assert.Equal (
  260. justifiedText,
  261. TextFormatter.ClipAndJustify (text, maxWidth, alignment, textDirection, tabWidth)
  262. );
  263. Assert.True (justifiedText.GetRuneCount () <= maxWidth);
  264. Assert.True (justifiedText.GetColumns () <= maxWidth);
  265. Assert.Equal (expectedClippedWidth, justifiedText.GetRuneCount ());
  266. Assert.Equal (
  267. expectedClippedWidth,
  268. justifiedText.ToRuneList ().Sum (r => Math.Max (r.GetColumns (), 1))
  269. );
  270. Assert.True (expectedClippedWidth <= maxWidth);
  271. Assert.Equal (
  272. StringExtensions.ToString (justifiedText.ToRunes () [..expectedClippedWidth]),
  273. justifiedText
  274. );
  275. }
  276. [Theory]
  277. [InlineData ("test", "", 0)]
  278. [InlineData ("test", "te", 2)]
  279. [InlineData ("test", "test", int.MaxValue)]
  280. [InlineData ("A sentence has words.", "A sentence has words.", 22)] // should fit
  281. [InlineData ("A sentence has words.", "A sentence has words.", 21)] // should fit
  282. [InlineData ("A sentence has words.", "A sentence has words.", int.MaxValue)] // should fit
  283. [InlineData ("A sentence has words.", "A sentence has words", 20)] // Should not fit
  284. [InlineData ("A sentence has words.", "A sentence", 10)] // Should not fit
  285. [InlineData ("A\tsentence\thas\twords.", "A sentence has words.", int.MaxValue)]
  286. [InlineData ("A\tsentence\thas\twords.", "A sentence", 10)]
  287. [InlineData ("line1\nline2\nline3long!", "line1\nline2\nline3long!", int.MaxValue)]
  288. [InlineData ("line1\nline2\nline3long!", "line1\nline", 10)]
  289. [InlineData (" ~  s  gui.cs   master ↑10", " ~  s  ", 10)] // Unicode
  290. [InlineData ("Ð ÑÐ", "Ð ÑÐ", 5)] // should fit
  291. [InlineData ("Ð ÑÐ", "Ð ÑÐ", 4)] // should fit
  292. [InlineData ("Ð ÑÐ", "Ð Ñ", 3)] // Should not fit
  293. public void ClipAndJustify_Valid_Right (string text, string justifiedText, int maxWidth)
  294. {
  295. var alignment = Alignment.End;
  296. var textDirection = TextDirection.LeftRight_BottomTop;
  297. var tabWidth = 1;
  298. Assert.Equal (
  299. justifiedText,
  300. TextFormatter.ClipAndJustify (text, maxWidth, alignment, textDirection, tabWidth)
  301. );
  302. int expectedClippedWidth = Math.Min (justifiedText.GetRuneCount (), maxWidth);
  303. Assert.Equal (
  304. justifiedText,
  305. TextFormatter.ClipAndJustify (text, maxWidth, alignment, textDirection, tabWidth)
  306. );
  307. Assert.True (justifiedText.GetRuneCount () <= maxWidth);
  308. Assert.True (justifiedText.GetColumns () <= maxWidth);
  309. Assert.Equal (expectedClippedWidth, justifiedText.GetRuneCount ());
  310. Assert.Equal (
  311. expectedClippedWidth,
  312. justifiedText.ToRuneList ().Sum (r => Math.Max (r.GetColumns (), 1))
  313. );
  314. Assert.True (expectedClippedWidth <= maxWidth);
  315. Assert.Equal (
  316. StringExtensions.ToString (justifiedText.ToRunes () [..expectedClippedWidth]),
  317. justifiedText
  318. );
  319. }
  320. [Theory]
  321. [InlineData (14, 1, TextDirection.LeftRight_TopBottom, "Les Misęrables")]
  322. [InlineData (1, 14, TextDirection.TopBottom_LeftRight, "L\ne\ns\n \nM\ni\ns\nę\nr\na\nb\nl\ne\ns")]
  323. [InlineData (
  324. 4,
  325. 4,
  326. TextDirection.TopBottom_LeftRight,
  327. @"
  328. LMre
  329. eias
  330. ssb
  331. ęl "
  332. )]
  333. public void Draw_With_Combining_Runes (int width, int height, TextDirection textDirection, string expected)
  334. {
  335. var driver = new FakeDriver ();
  336. driver.Init ();
  337. var text = "Les Mise\u0328\u0301rables";
  338. var tf = new TextFormatter ();
  339. tf.Direction = textDirection;
  340. tf.Text = text;
  341. Assert.True (tf.WordWrap);
  342. tf.ConstrainToSize = new (width, height);
  343. tf.Draw (
  344. new (0, 0, width, height),
  345. new (ColorName.White, ColorName.Black),
  346. new (ColorName.Blue, ColorName.Black),
  347. default (Rectangle),
  348. driver
  349. );
  350. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output, driver);
  351. driver.End ();
  352. }
  353. [Fact]
  354. [SetupFakeDriver]
  355. public void FillRemaining_True_False ()
  356. {
  357. ((FakeDriver)Application.Driver).SetBufferSize (22, 5);
  358. Attribute [] attrs =
  359. {
  360. Attribute.Default, new (ColorName.Green, ColorName.BrightMagenta),
  361. new (ColorName.Blue, ColorName.Cyan)
  362. };
  363. var tf = new TextFormatter { ConstrainToSize = new (14, 3), Text = "Test\nTest long\nTest long long\n", MultiLine = true };
  364. tf.Draw (
  365. new (1, 1, 19, 3),
  366. attrs [1],
  367. attrs [2]);
  368. Assert.False (tf.FillRemaining);
  369. TestHelpers.AssertDriverContentsWithFrameAre (
  370. @"
  371. Test
  372. Test long
  373. Test long long",
  374. _output);
  375. TestHelpers.AssertDriverAttributesAre (
  376. @"
  377. 000000000000000000000
  378. 011110000000000000000
  379. 011111111100000000000
  380. 011111111111111000000
  381. 000000000000000000000",
  382. null,
  383. attrs);
  384. tf.FillRemaining = true;
  385. tf.Draw (
  386. new (1, 1, 19, 3),
  387. attrs [1],
  388. attrs [2]);
  389. TestHelpers.AssertDriverAttributesAre (
  390. @"
  391. 000000000000000000000
  392. 011111111111111111110
  393. 011111111111111111110
  394. 011111111111111111110
  395. 000000000000000000000",
  396. null,
  397. attrs);
  398. }
  399. [Theory]
  400. [InlineData ("_k Before", true, 0, (KeyCode)'K')] // lower case should return uppercase Hotkey
  401. [InlineData ("a_k Second", true, 1, (KeyCode)'K')]
  402. [InlineData ("Last _k", true, 5, (KeyCode)'K')]
  403. [InlineData ("After k_", false, -1, KeyCode.Null)]
  404. [InlineData ("Multiple _k and _R", true, 9, (KeyCode)'K')]
  405. [InlineData ("Non-english: _кдать", true, 13, (KeyCode)'к')] // Lower case Cryllic K (к)
  406. [InlineData ("_k Before", true, 0, (KeyCode)'K', true)] // Turn on FirstUpperCase and verify same results
  407. [InlineData ("a_k Second", true, 1, (KeyCode)'K', true)]
  408. [InlineData ("Last _k", true, 5, (KeyCode)'K', true)]
  409. [InlineData ("After k_", false, -1, KeyCode.Null, true)]
  410. [InlineData ("Multiple _k and _r", true, 9, (KeyCode)'K', true)]
  411. [InlineData ("Non-english: _кдать", true, 13, (KeyCode)'к', true)] // Cryllic K (К)
  412. public void FindHotKey_AlphaLowerCase_Succeeds (
  413. string text,
  414. bool expectedResult,
  415. int expectedHotPos,
  416. KeyCode expectedKey,
  417. bool supportFirstUpperCase = false
  418. )
  419. {
  420. var hotKeySpecifier = (Rune)'_';
  421. bool result = TextFormatter.FindHotKey (
  422. text,
  423. hotKeySpecifier,
  424. out int hotPos,
  425. out Key hotKey,
  426. supportFirstUpperCase
  427. );
  428. if (expectedResult)
  429. {
  430. Assert.True (result);
  431. }
  432. else
  433. {
  434. Assert.False (result);
  435. }
  436. Assert.Equal (expectedResult, result);
  437. Assert.Equal (expectedHotPos, hotPos);
  438. Assert.Equal (expectedKey, hotKey);
  439. }
  440. [Theory]
  441. [InlineData ("_K Before", true, 0, (KeyCode)'K')]
  442. [InlineData ("a_K Second", true, 1, (KeyCode)'K')]
  443. [InlineData ("Last _K", true, 5, (KeyCode)'K')]
  444. [InlineData ("After K_", false, -1, KeyCode.Null)]
  445. [InlineData ("Multiple _K and _R", true, 9, (KeyCode)'K')]
  446. [InlineData ("Non-english: _Кдать", true, 13, (KeyCode)'К')] // Cryllic K (К)
  447. [InlineData ("_K Before", true, 0, (KeyCode)'K', true)] // Turn on FirstUpperCase and verify same results
  448. [InlineData ("a_K Second", true, 1, (KeyCode)'K', true)]
  449. [InlineData ("Last _K", true, 5, (KeyCode)'K', true)]
  450. [InlineData ("After K_", false, -1, KeyCode.Null, true)]
  451. [InlineData ("Multiple _K and _R", true, 9, (KeyCode)'K', true)]
  452. [InlineData ("Non-english: _Кдать", true, 13, (KeyCode)'К', true)] // Cryllic K (К)
  453. public void FindHotKey_AlphaUpperCase_Succeeds (
  454. string text,
  455. bool expectedResult,
  456. int expectedHotPos,
  457. KeyCode expectedKey,
  458. bool supportFirstUpperCase = false
  459. )
  460. {
  461. var hotKeySpecifier = (Rune)'_';
  462. bool result = TextFormatter.FindHotKey (
  463. text,
  464. hotKeySpecifier,
  465. out int hotPos,
  466. out Key hotKey,
  467. supportFirstUpperCase
  468. );
  469. if (expectedResult)
  470. {
  471. Assert.True (result);
  472. }
  473. else
  474. {
  475. Assert.False (result);
  476. }
  477. Assert.Equal (expectedResult, result);
  478. Assert.Equal (expectedHotPos, hotPos);
  479. Assert.Equal (expectedKey, hotKey);
  480. }
  481. [Theory]
  482. [InlineData (null)]
  483. [InlineData ("")]
  484. [InlineData ("no hotkey")]
  485. [InlineData ("No hotkey, Upper Case")]
  486. [InlineData ("Non-english: Сохранить")]
  487. public void FindHotKey_Invalid_ReturnsFalse (string text)
  488. {
  489. var hotKeySpecifier = (Rune)'_';
  490. var supportFirstUpperCase = false;
  491. var hotPos = 0;
  492. Key hotKey = KeyCode.Null;
  493. var result = false;
  494. result = TextFormatter.FindHotKey (
  495. text,
  496. hotKeySpecifier,
  497. out hotPos,
  498. out hotKey,
  499. supportFirstUpperCase
  500. );
  501. Assert.False (result);
  502. Assert.Equal (-1, hotPos);
  503. Assert.Equal (KeyCode.Null, hotKey);
  504. }
  505. [Theory]
  506. [InlineData ("\"k before")]
  507. [InlineData ("ak second")]
  508. [InlineData ("last k")]
  509. [InlineData ("multiple k and r")]
  510. [InlineData ("12345")]
  511. [InlineData ("`~!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?")] // punctuation
  512. [InlineData (" ~  s  gui.cs   master ↑10")] // ~IsLetterOrDigit + Unicode
  513. [InlineData ("non-english: кдать")] // Lower case Cryllic K (к)
  514. public void FindHotKey_Legacy_FirstUpperCase_NotFound_Returns_False (string text)
  515. {
  516. var supportFirstUpperCase = true;
  517. var hotKeySpecifier = (Rune)0;
  518. bool result = TextFormatter.FindHotKey (
  519. text,
  520. hotKeySpecifier,
  521. out int hotPos,
  522. out Key hotKey,
  523. supportFirstUpperCase
  524. );
  525. Assert.False (result);
  526. Assert.Equal (-1, hotPos);
  527. Assert.Equal (KeyCode.Null, hotKey);
  528. }
  529. [Theory]
  530. [InlineData ("K Before", true, 0, (KeyCode)'K')]
  531. [InlineData ("aK Second", true, 1, (KeyCode)'K')]
  532. [InlineData ("last K", true, 5, (KeyCode)'K')]
  533. [InlineData ("multiple K and R", true, 9, (KeyCode)'K')]
  534. [InlineData ("non-english: Кдать", true, 13, (KeyCode)'К')] // Cryllic K (К)
  535. public void FindHotKey_Legacy_FirstUpperCase_Succeeds (
  536. string text,
  537. bool expectedResult,
  538. int expectedHotPos,
  539. KeyCode expectedKey
  540. )
  541. {
  542. var supportFirstUpperCase = true;
  543. var hotKeySpecifier = (Rune)0;
  544. bool result = TextFormatter.FindHotKey (
  545. text,
  546. hotKeySpecifier,
  547. out int hotPos,
  548. out Key hotKey,
  549. supportFirstUpperCase
  550. );
  551. if (expectedResult)
  552. {
  553. Assert.True (result);
  554. }
  555. else
  556. {
  557. Assert.False (result);
  558. }
  559. Assert.Equal (expectedResult, result);
  560. Assert.Equal (expectedHotPos, hotPos);
  561. Assert.Equal (expectedKey, hotKey);
  562. }
  563. [Theory]
  564. [InlineData ("_1 Before", true, 0, (KeyCode)'1')] // Digits
  565. [InlineData ("a_1 Second", true, 1, (KeyCode)'1')]
  566. [InlineData ("Last _1", true, 5, (KeyCode)'1')]
  567. [InlineData ("After 1_", false, -1, KeyCode.Null)]
  568. [InlineData ("Multiple _1 and _2", true, 9, (KeyCode)'1')]
  569. [InlineData ("_1 Before", true, 0, (KeyCode)'1', true)] // Turn on FirstUpperCase and verify same results
  570. [InlineData ("a_1 Second", true, 1, (KeyCode)'1', true)]
  571. [InlineData ("Last _1", true, 5, (KeyCode)'1', true)]
  572. [InlineData ("After 1_", false, -1, KeyCode.Null, true)]
  573. [InlineData ("Multiple _1 and _2", true, 9, (KeyCode)'1', true)]
  574. public void FindHotKey_Numeric_Succeeds (
  575. string text,
  576. bool expectedResult,
  577. int expectedHotPos,
  578. KeyCode expectedKey,
  579. bool supportFirstUpperCase = false
  580. )
  581. {
  582. var hotKeySpecifier = (Rune)'_';
  583. bool result = TextFormatter.FindHotKey (
  584. text,
  585. hotKeySpecifier,
  586. out int hotPos,
  587. out Key hotKey,
  588. supportFirstUpperCase
  589. );
  590. if (expectedResult)
  591. {
  592. Assert.True (result);
  593. }
  594. else
  595. {
  596. Assert.False (result);
  597. }
  598. Assert.Equal (expectedResult, result);
  599. Assert.Equal (expectedHotPos, hotPos);
  600. Assert.Equal (expectedKey, hotKey);
  601. }
  602. [Theory]
  603. [InlineData ("_\"k before", true, (KeyCode)'"')] // BUGBUG: Not sure why this fails. " is a normal char
  604. [InlineData ("\"_k before", true, KeyCode.K)]
  605. [InlineData ("_`~!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?", true, (KeyCode)'`')]
  606. [InlineData ("`_~!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?", true, (KeyCode)'~')]
  607. [InlineData (
  608. "`~!@#$%^&*()-__=+[{]}\\|;:'\",<.>/?",
  609. true,
  610. (KeyCode)'='
  611. )] // BUGBUG: Not sure why this fails. Ignore the first and consider the second
  612. [InlineData ("_ ~  s  gui.cs   master ↑10", true, (KeyCode)'')] // ~IsLetterOrDigit + Unicode
  613. [InlineData (" ~  s  gui.cs  _ master ↑10", true, (KeyCode)'')] // ~IsLetterOrDigit + Unicode
  614. [InlineData ("non-english: _кдать", true, (KeyCode)'к')] // Lower case Cryllic K (к)
  615. public void FindHotKey_Symbols_Returns_Symbol (string text, bool found, KeyCode expected)
  616. {
  617. var hotKeySpecifier = (Rune)'_';
  618. bool result = TextFormatter.FindHotKey (text, hotKeySpecifier, out int _, out Key hotKey);
  619. Assert.Equal (found, result);
  620. Assert.Equal (expected, hotKey);
  621. }
  622. [Fact]
  623. public void Format_Dont_Throw_ArgumentException_With_WordWrap_As_False_And_Keep_End_Spaces_As_True ()
  624. {
  625. Exception exception = Record.Exception (
  626. () =>
  627. TextFormatter.Format (
  628. "Some text",
  629. 4,
  630. Alignment.Start,
  631. false,
  632. true
  633. )
  634. );
  635. Assert.Null (exception);
  636. }
  637. [Theory]
  638. [InlineData (
  639. "Hello world, how are you today? Pretty neat!",
  640. 44,
  641. 80,
  642. "Hello world, how are you today? Pretty neat!"
  643. )]
  644. public void Format_Justified_Always_Returns_Text_Width_Equal_To_Passed_Width_Horizontal (
  645. string text,
  646. int runeCount,
  647. int maxWidth,
  648. string justifiedText
  649. )
  650. {
  651. Assert.Equal (runeCount, text.GetRuneCount ());
  652. var fmtText = string.Empty;
  653. for (int i = text.GetRuneCount (); i < maxWidth; i++)
  654. {
  655. fmtText = TextFormatter.Format (text, i, Alignment.Fill, true) [0];
  656. Assert.Equal (i, fmtText.GetRuneCount ());
  657. char c = fmtText [^1];
  658. Assert.True (text.EndsWith (c));
  659. }
  660. Assert.Equal (justifiedText, fmtText);
  661. }
  662. [Theory]
  663. [InlineData (
  664. "Hello world, how are you today? Pretty neat!",
  665. 44,
  666. 80,
  667. "Hello world, how are you today? Pretty neat!"
  668. )]
  669. public void Format_Justified_Always_Returns_Text_Width_Equal_To_Passed_Width_Vertical (
  670. string text,
  671. int runeCount,
  672. int maxWidth,
  673. string justifiedText
  674. )
  675. {
  676. Assert.Equal (runeCount, text.GetRuneCount ());
  677. var fmtText = string.Empty;
  678. for (int i = text.GetRuneCount (); i < maxWidth; i++)
  679. {
  680. fmtText = TextFormatter.Format (
  681. text,
  682. i,
  683. Alignment.Fill,
  684. false,
  685. true,
  686. 0,
  687. TextDirection.TopBottom_LeftRight
  688. ) [0];
  689. Assert.Equal (i, fmtText.GetRuneCount ());
  690. char c = fmtText [^1];
  691. Assert.True (text.EndsWith (c));
  692. }
  693. Assert.Equal (justifiedText, fmtText);
  694. }
  695. [Theory]
  696. [InlineData ("Truncate", 3, "Tru")]
  697. [InlineData ("デモエムポンズ", 3, "デ")]
  698. public void Format_Truncate_Simple_And_Wide_Runes (string text, int width, string expected)
  699. {
  700. List<string> list = TextFormatter.Format (text, width, false, false);
  701. Assert.Equal (expected, list [^1]);
  702. }
  703. [Theory]
  704. [MemberData (nameof (FormatEnvironmentNewLine))]
  705. public void Format_With_PreserveTrailingSpaces_And_Without_PreserveTrailingSpaces (
  706. string text,
  707. int width,
  708. IEnumerable<string> expected
  709. )
  710. {
  711. var preserveTrailingSpaces = false;
  712. List<string> formated = TextFormatter.Format (text, width, false, true, preserveTrailingSpaces);
  713. Assert.Equal (expected, formated);
  714. preserveTrailingSpaces = true;
  715. formated = TextFormatter.Format (text, width, false, true, preserveTrailingSpaces);
  716. Assert.Equal (expected, formated);
  717. }
  718. [Theory]
  719. [InlineData (
  720. " A sentence has words. \n This is the second Line - 2. ",
  721. 4,
  722. -50,
  723. Alignment.Start,
  724. true,
  725. false,
  726. new [] { " A", "sent", "ence", "has", "word", "s. ", " Thi", "s is", "the", "seco", "nd", "Line", "- 2." },
  727. " Asentencehaswords. This isthesecondLine- 2."
  728. )]
  729. [InlineData (
  730. " A sentence has words. \n This is the second Line - 2. ",
  731. 4,
  732. -50,
  733. Alignment.Start,
  734. true,
  735. true,
  736. new []
  737. {
  738. " A ",
  739. "sent",
  740. "ence",
  741. " ",
  742. "has ",
  743. "word",
  744. "s. ",
  745. " ",
  746. "This",
  747. " is ",
  748. "the ",
  749. "seco",
  750. "nd ",
  751. "Line",
  752. " - ",
  753. "2. "
  754. },
  755. " A sentence has words. This is the second Line - 2. "
  756. )]
  757. public void Format_WordWrap_PreserveTrailingSpaces (
  758. string text,
  759. int maxWidth,
  760. int widthOffset,
  761. Alignment alignment,
  762. bool wrap,
  763. bool preserveTrailingSpaces,
  764. IEnumerable<string> resultLines,
  765. string expectedWrappedText
  766. )
  767. {
  768. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  769. List<string> list = TextFormatter.Format (text, maxWidth, alignment, wrap, preserveTrailingSpaces);
  770. Assert.Equal (list.Count, resultLines.Count ());
  771. Assert.Equal (resultLines, list);
  772. var wrappedText = string.Empty;
  773. foreach (string txt in list)
  774. {
  775. wrappedText += txt;
  776. }
  777. Assert.Equal (expectedWrappedText, wrappedText);
  778. }
  779. [Theory]
  780. [InlineData ("Hello World", 11)]
  781. [InlineData ("こんにちは世界", 14)]
  782. public void GetColumns_Simple_And_Wide_Runes (string text, int width) { Assert.Equal (width, text.GetColumns ()); }
  783. [Theory]
  784. [InlineData ("Hello World", 6, 6)]
  785. [InlineData ("こんにちは 世界", 6, 3)]
  786. [MemberData (nameof (CMGlyphs))]
  787. public void GetLengthThatFits_List_Simple_And_Wide_Runes (string text, int columns, int expectedLength)
  788. {
  789. List<Rune> runes = text.ToRuneList ();
  790. Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (runes, columns));
  791. }
  792. [Theory]
  793. [InlineData ("test", 3, 3)]
  794. [InlineData ("test", 4, 4)]
  795. [InlineData ("test", 10, 4)]
  796. public void GetLengthThatFits_Runelist (string text, int columns, int expectedLength)
  797. {
  798. List<Rune> runes = text.ToRuneList ();
  799. Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (runes, columns));
  800. }
  801. [Theory]
  802. [InlineData ("Hello World", 6, 6)]
  803. [InlineData ("こんにちは 世界", 6, 3)]
  804. public void GetLengthThatFits_Simple_And_Wide_Runes (string text, int columns, int expectedLength)
  805. {
  806. Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (text, columns));
  807. }
  808. [Theory]
  809. [InlineData ("test", 3, 3)]
  810. [InlineData ("test", 4, 4)]
  811. [InlineData ("test", 10, 4)]
  812. [InlineData ("test", 1, 1)]
  813. [InlineData ("test", 0, 0)]
  814. [InlineData ("test", -1, 0)]
  815. [InlineData (null, -1, 0)]
  816. [InlineData ("", -1, 0)]
  817. public void GetLengthThatFits_String (string text, int columns, int expectedLength)
  818. {
  819. Assert.Equal (expectedLength, TextFormatter.GetLengthThatFits (text, columns));
  820. }
  821. [Fact]
  822. public void GetLengthThatFits_With_Combining_Runes ()
  823. {
  824. var text = "Les Mise\u0328\u0301rables";
  825. Assert.Equal (16, TextFormatter.GetLengthThatFits (text, 14));
  826. }
  827. [Fact]
  828. public void GetMaxColsForWidth_With_Combining_Runes ()
  829. {
  830. List<string> text = new () { "Les Mis", "e\u0328\u0301", "rables" };
  831. Assert.Equal (1, TextFormatter.GetMaxColsForWidth (text, 1));
  832. }
  833. [Theory]
  834. [InlineData (new [] { "0123456789" }, 1)]
  835. [InlineData (new [] { "Hello World" }, 1)]
  836. [InlineData (new [] { "Hello", "World" }, 2)]
  837. [InlineData (new [] { "こんにちは", "世界" }, 4)]
  838. public void GetColumnsRequiredForVerticalText_List_GetsWidth (IEnumerable<string> text, int expectedWidth)
  839. {
  840. Assert.Equal (expectedWidth, TextFormatter.GetColumnsRequiredForVerticalText (text.ToList ()));
  841. }
  842. [Theory]
  843. [InlineData (new [] { "Hello World" }, 1, 0, 1, 1)]
  844. [InlineData (new [] { "Hello", "World" }, 2, 1, 1, 1)]
  845. [InlineData (new [] { "こんにちは", "世界" }, 4, 1, 1, 2)]
  846. public void GetColumnsRequiredForVerticalText_List_Simple_And_Wide_Runes (
  847. IEnumerable<string> text,
  848. int expectedWidth,
  849. int index,
  850. int length,
  851. int expectedIndexWidth
  852. )
  853. {
  854. Assert.Equal (expectedWidth, TextFormatter.GetColumnsRequiredForVerticalText (text.ToList ()));
  855. Assert.Equal (expectedIndexWidth, TextFormatter.GetColumnsRequiredForVerticalText (text.ToList (), index, length));
  856. }
  857. [Fact]
  858. public void GetColumnsRequiredForVerticalText_List_With_Combining_Runes ()
  859. {
  860. List<string> text = new () { "Les Mis", "e\u0328\u0301", "rables" };
  861. Assert.Equal (1, TextFormatter.GetColumnsRequiredForVerticalText (text, 1, 1));
  862. }
  863. //[Fact]
  864. //public void GetWidestLineLength_With_Combining_Runes ()
  865. //{
  866. // var text = "Les Mise\u0328\u0301rables";
  867. // Assert.Equal (1, TextFormatter.GetWidestLineLength (text, 1, 1));
  868. //}
  869. [Fact]
  870. public void Internal_Tests ()
  871. {
  872. var tf = new TextFormatter ();
  873. Assert.Equal (KeyCode.Null, tf.HotKey);
  874. tf.HotKey = KeyCode.CtrlMask | KeyCode.Q;
  875. Assert.Equal (KeyCode.CtrlMask | KeyCode.Q, tf.HotKey);
  876. }
  877. [Theory]
  878. [InlineData ("")]
  879. [InlineData (null)]
  880. [InlineData ("test")]
  881. public void Justify_Invalid (string text)
  882. {
  883. Assert.Equal (text, TextFormatter.Justify (text, 0));
  884. Assert.Equal (text, TextFormatter.Justify (text, 0));
  885. Assert.Throws<ArgumentOutOfRangeException> (() => TextFormatter.Justify (text, -1));
  886. }
  887. [Theory]
  888. // Even # of spaces
  889. // 0123456789
  890. [InlineData ("012 456 89", "012 456 89", 10, 0, "+", true)]
  891. [InlineData ("012 456 89", "012++456+89", 11, 1)]
  892. [InlineData ("012 456 89", "012 456 89", 12, 2, "++", true)]
  893. [InlineData ("012 456 89", "012+++456++89", 13, 3)]
  894. [InlineData ("012 456 89", "012 456 89", 14, 4, "+++", true)]
  895. [InlineData ("012 456 89", "012++++456+++89", 15, 5)]
  896. [InlineData ("012 456 89", "012 456 89", 16, 6, "++++", true)]
  897. [InlineData ("012 456 89", "012 456 89", 30, 20, "+++++++++++", true)]
  898. [InlineData ("012 456 89", "012+++++++++++++456++++++++++++89", 33, 23)]
  899. // Odd # of spaces
  900. // 01234567890123
  901. [InlineData ("012 456 89 end", "012 456 89 end", 14, 0, "+", true)]
  902. [InlineData ("012 456 89 end", "012++456+89+end", 15, 1)]
  903. [InlineData ("012 456 89 end", "012++456++89+end", 16, 2)]
  904. [InlineData ("012 456 89 end", "012 456 89 end", 17, 3, "++", true)]
  905. [InlineData ("012 456 89 end", "012+++456++89++end", 18, 4)]
  906. [InlineData ("012 456 89 end", "012+++456+++89++end", 19, 5)]
  907. [InlineData ("012 456 89 end", "012 456 89 end", 20, 6, "+++", true)]
  908. [InlineData ("012 456 89 end", "012++++++++456++++++++89+++++++end", 34, 20)]
  909. [InlineData ("012 456 89 end", "012+++++++++456+++++++++89++++++++end", 37, 23)]
  910. // Unicode
  911. // Even # of chars
  912. // 0123456789
  913. [InlineData ("пÑРвРÑ", "пÑРвРÑ", 10, 0, "+", true)]
  914. [InlineData ("пÑРвРÑ", "пÑÐ++вÐ+Ñ", 11, 1)]
  915. [InlineData ("пÑРвРÑ", "пÑРвРÑ", 12, 2, "++", true)]
  916. [InlineData ("пÑРвРÑ", "пÑÐ+++вÐ++Ñ", 13, 3)]
  917. [InlineData ("пÑРвРÑ", "пÑРвРÑ", 14, 4, "+++", true)]
  918. [InlineData ("пÑРвРÑ", "пÑÐ++++вÐ+++Ñ", 15, 5)]
  919. [InlineData ("пÑРвРÑ", "пÑРвРÑ", 16, 6, "++++", true)]
  920. [InlineData ("пÑРвРÑ", "пÑРвРÑ", 30, 20, "+++++++++++", true)]
  921. [InlineData ("пÑРвРÑ", "пÑÐ+++++++++++++вÐ++++++++++++Ñ", 33, 23)]
  922. // Unicode
  923. // Odd # of chars
  924. // 0123456789
  925. [InlineData ("Ð ÑРвРÑ", "Ð ÑРвРÑ", 10, 0, "+", true)]
  926. [InlineData ("Ð ÑРвРÑ", "Ð++ÑÐ+вÐ+Ñ", 11, 1)]
  927. [InlineData ("Ð ÑРвРÑ", "Ð++ÑÐ++вÐ+Ñ", 12, 2)]
  928. [InlineData ("Ð ÑРвРÑ", "Ð ÑРвРÑ", 13, 3, "++", true)]
  929. [InlineData ("Ð ÑРвРÑ", "Ð+++ÑÐ++вÐ++Ñ", 14, 4)]
  930. [InlineData ("Ð ÑРвРÑ", "Ð+++ÑÐ+++вÐ++Ñ", 15, 5)]
  931. [InlineData ("Ð ÑРвРÑ", "Ð ÑРвРÑ", 16, 6, "+++", true)]
  932. [InlineData ("Ð ÑРвРÑ", "Ð++++++++ÑÐ++++++++вÐ+++++++Ñ", 30, 20)]
  933. [InlineData ("Ð ÑРвРÑ", "Ð+++++++++ÑÐ+++++++++вÐ++++++++Ñ", 33, 23)]
  934. public void Justify_Sentence (
  935. string text,
  936. string justifiedText,
  937. int forceToWidth,
  938. int widthOffset,
  939. string replaceWith = null,
  940. bool replace = false
  941. )
  942. {
  943. var fillChar = '+';
  944. Assert.Equal (forceToWidth, text.GetRuneCount () + widthOffset);
  945. if (replace)
  946. {
  947. justifiedText = text.Replace (" ", replaceWith);
  948. }
  949. Assert.Equal (justifiedText, TextFormatter.Justify (text, forceToWidth, fillChar));
  950. Assert.True (Math.Abs (forceToWidth - justifiedText.GetRuneCount ()) < text.Count (s => s == ' '));
  951. Assert.True (Math.Abs (forceToWidth - justifiedText.GetColumns ()) < text.Count (s => s == ' '));
  952. }
  953. [Theory]
  954. [InlineData ("word")] // Even # of chars
  955. [InlineData ("word.")] // Odd # of chars
  956. [InlineData ("пÑивеÑ")] // Unicode (even #)
  957. [InlineData ("пÑивеÑ.")] // Unicode (odd # of chars)
  958. public void Justify_SingleWord (string text)
  959. {
  960. string justifiedText = text;
  961. var fillChar = '+';
  962. int width = text.GetRuneCount ();
  963. Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar));
  964. width = text.GetRuneCount () + 1;
  965. Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar));
  966. width = text.GetRuneCount () + 2;
  967. Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar));
  968. width = text.GetRuneCount () + 10;
  969. Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar));
  970. width = text.GetRuneCount () + 11;
  971. Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar));
  972. }
  973. [Theory]
  974. [InlineData ("Single Line 界", 14)]
  975. [InlineData ("First Line 界\nSecond Line 界\nThird Line 界\n", 14)]
  976. public void MaxWidthLine_With_And_Without_Newlines (string text, int expected) { Assert.Equal (expected, TextFormatter.GetWidestLineLength (text)); }
  977. [Theory]
  978. [InlineData (
  979. "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
  980. 0,
  981. 0,
  982. false,
  983. new [] { "" }
  984. )]
  985. [InlineData (
  986. "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
  987. 0,
  988. 1,
  989. false,
  990. new [] { "" }
  991. )]
  992. [InlineData (
  993. "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
  994. 1,
  995. 0,
  996. false,
  997. new [] { "" }
  998. )]
  999. [InlineData (
  1000. "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
  1001. 0,
  1002. 0,
  1003. true,
  1004. new [] { "" }
  1005. )]
  1006. [InlineData (
  1007. "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
  1008. 0,
  1009. 1,
  1010. true,
  1011. new [] { "" }
  1012. )]
  1013. [InlineData (
  1014. "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
  1015. 1,
  1016. 0,
  1017. true,
  1018. new [] { "" }
  1019. )]
  1020. [InlineData (
  1021. "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
  1022. 6,
  1023. 5,
  1024. false,
  1025. new [] { "First " }
  1026. )]
  1027. [InlineData ("1\n2\n3\n4\n5\n6", 6, 5, false, new [] { "1 2 3 " })]
  1028. [InlineData (
  1029. "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
  1030. 6,
  1031. 5,
  1032. true,
  1033. new [] { "First ", "Second", "Third ", "Forty ", "Fiftee" }
  1034. )]
  1035. [InlineData ("第一行\n第二行\n第三行\n四十行\n第十五行\n七十行", 5, 5, false, new [] { "第一" })]
  1036. [InlineData ("第一行\n第二行\n第三行\n四十行\n第十五行\n七十行", 5, 5, true, new [] { "第一", "第二", "第三", "四十", "第十" })]
  1037. public void MultiLine_WordWrap_False_Horizontal_Direction (
  1038. string text,
  1039. int maxWidth,
  1040. int maxHeight,
  1041. bool multiLine,
  1042. IEnumerable<string> resultLines
  1043. )
  1044. {
  1045. var tf = new TextFormatter
  1046. {
  1047. Text = text, ConstrainToSize = new (maxWidth, maxHeight), WordWrap = false, MultiLine = multiLine
  1048. };
  1049. Assert.False (tf.WordWrap);
  1050. Assert.True (tf.MultiLine == multiLine);
  1051. Assert.Equal (TextDirection.LeftRight_TopBottom, tf.Direction);
  1052. List<string> splitLines = tf.GetLines ();
  1053. Assert.Equal (splitLines.Count, resultLines.Count ());
  1054. Assert.Equal (splitLines, resultLines);
  1055. }
  1056. [Theory]
  1057. [InlineData (
  1058. "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
  1059. 0,
  1060. 0,
  1061. false,
  1062. new [] { "" }
  1063. )]
  1064. [InlineData (
  1065. "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
  1066. 0,
  1067. 1,
  1068. false,
  1069. new [] { "" }
  1070. )]
  1071. [InlineData (
  1072. "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
  1073. 1,
  1074. 0,
  1075. false,
  1076. new [] { "" }
  1077. )]
  1078. [InlineData (
  1079. "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
  1080. 0,
  1081. 0,
  1082. true,
  1083. new [] { "" }
  1084. )]
  1085. [InlineData (
  1086. "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
  1087. 0,
  1088. 1,
  1089. true,
  1090. new [] { "" }
  1091. )]
  1092. [InlineData (
  1093. "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
  1094. 1,
  1095. 0,
  1096. true,
  1097. new [] { "" }
  1098. )]
  1099. [InlineData (
  1100. "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
  1101. 6,
  1102. 5,
  1103. false,
  1104. new [] { "First" }
  1105. )]
  1106. [InlineData ("1\n2\n3\n4\n5\n6", 6, 5, false, new [] { "1 2 3" })]
  1107. [InlineData (
  1108. "First Line\nSecond Line\nThird Line\nForty Line\nFifteenth Line\nSeventy Line",
  1109. 6,
  1110. 5,
  1111. true,
  1112. new [] { "First", "Secon", "Third", "Forty", "Fifte", "Seven" }
  1113. )]
  1114. [InlineData ("第一行\n第二行\n第三行\n四十行\n第十五行\n七十行", 5, 5, false, new [] { "第一行 第" })]
  1115. [InlineData ("第一行\n第二行\n第三行\n四十行\n第十五行\n七十行", 5, 5, true, new [] { "第一行", "第二行" })]
  1116. public void MultiLine_WordWrap_False_Vertical_Direction (
  1117. string text,
  1118. int maxWidth,
  1119. int maxHeight,
  1120. bool multiLine,
  1121. IEnumerable<string> resultLines
  1122. )
  1123. {
  1124. var tf = new TextFormatter
  1125. {
  1126. Text = text,
  1127. ConstrainToSize = new (maxWidth, maxHeight),
  1128. WordWrap = false,
  1129. MultiLine = multiLine,
  1130. Direction = TextDirection.TopBottom_LeftRight
  1131. };
  1132. Assert.False (tf.WordWrap);
  1133. Assert.True (tf.MultiLine == multiLine);
  1134. Assert.Equal (TextDirection.TopBottom_LeftRight, tf.Direction);
  1135. List<string> splitLines = tf.GetLines ();
  1136. Assert.Equal (splitLines.Count, resultLines.Count ());
  1137. Assert.Equal (splitLines, resultLines);
  1138. }
  1139. [Fact]
  1140. public void NeedsFormat_Sets ()
  1141. {
  1142. var testText = "test";
  1143. var testBounds = new Rectangle (0, 0, 100, 1);
  1144. var tf = new TextFormatter ();
  1145. tf.Text = "test";
  1146. Assert.True (tf.NeedsFormat); // get_Lines causes a Format
  1147. Assert.NotEmpty (tf.GetLines ());
  1148. Assert.False (tf.NeedsFormat); // get_Lines causes a Format
  1149. Assert.Equal (testText, tf.Text);
  1150. tf.Draw (testBounds, new (), new ());
  1151. Assert.False (tf.NeedsFormat);
  1152. tf.ConstrainToSize = new (1, 1);
  1153. Assert.True (tf.NeedsFormat);
  1154. Assert.NotEmpty (tf.GetLines ());
  1155. Assert.False (tf.NeedsFormat); // get_Lines causes a Format
  1156. tf.Alignment = Alignment.Center;
  1157. Assert.True (tf.NeedsFormat);
  1158. Assert.NotEmpty (tf.GetLines ());
  1159. Assert.False (tf.NeedsFormat); // get_Lines causes a Format
  1160. }
  1161. [Theory]
  1162. [InlineData ("", -1, Alignment.Start, false, 0)]
  1163. [InlineData (null, 0, Alignment.Start, false, 1)]
  1164. [InlineData (null, 0, Alignment.Start, true, 1)]
  1165. [InlineData ("", 0, Alignment.Start, false, 1)]
  1166. [InlineData ("", 0, Alignment.Start, true, 1)]
  1167. public void Reformat_Invalid (string text, int maxWidth, Alignment alignment, bool wrap, int linesCount)
  1168. {
  1169. if (maxWidth < 0)
  1170. {
  1171. Assert.Throws<ArgumentOutOfRangeException> (
  1172. () =>
  1173. TextFormatter.Format (text, maxWidth, alignment, wrap)
  1174. );
  1175. }
  1176. else
  1177. {
  1178. List<string> list = TextFormatter.Format (text, maxWidth, alignment, wrap);
  1179. Assert.NotEmpty (list);
  1180. Assert.True (list.Count == linesCount);
  1181. Assert.Equal (string.Empty, list [0]);
  1182. }
  1183. }
  1184. [Theory]
  1185. [InlineData ("A sentence has words.\nLine 2.", 0, -29, Alignment.Start, false, 1, true)]
  1186. [InlineData ("A sentence has words.\nLine 2.", 1, -28, Alignment.Start, false, 1, false)]
  1187. [InlineData ("A sentence has words.\nLine 2.", 5, -24, Alignment.Start, false, 1, false)]
  1188. [InlineData ("A sentence has words.\nLine 2.", 28, -1, Alignment.Start, false, 1, false)]
  1189. // no clip
  1190. [InlineData ("A sentence has words.\nLine 2.", 29, 0, Alignment.Start, false, 1, false)]
  1191. [InlineData ("A sentence has words.\nLine 2.", 30, 1, Alignment.Start, false, 1, false)]
  1192. [InlineData ("A sentence has words.\r\nLine 2.", 0, -30, Alignment.Start, false, 1, true)]
  1193. [InlineData ("A sentence has words.\r\nLine 2.", 1, -29, Alignment.Start, false, 1, false)]
  1194. [InlineData ("A sentence has words.\r\nLine 2.", 5, -25, Alignment.Start, false, 1, false)]
  1195. [InlineData ("A sentence has words.\r\nLine 2.", 29, -1, Alignment.Start, false, 1, false, 1)]
  1196. [InlineData ("A sentence has words.\r\nLine 2.", 30, 0, Alignment.Start, false, 1, false)]
  1197. [InlineData ("A sentence has words.\r\nLine 2.", 31, 1, Alignment.Start, false, 1, false)]
  1198. public void Reformat_NoWordrap_NewLines_MultiLine_False (
  1199. string text,
  1200. int maxWidth,
  1201. int widthOffset,
  1202. Alignment alignment,
  1203. bool wrap,
  1204. int linesCount,
  1205. bool stringEmpty,
  1206. int clipWidthOffset = 0
  1207. )
  1208. {
  1209. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  1210. int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth) + clipWidthOffset;
  1211. List<string> list = TextFormatter.Format (text, maxWidth, alignment, wrap);
  1212. Assert.NotEmpty (list);
  1213. Assert.True (list.Count == linesCount);
  1214. if (stringEmpty)
  1215. {
  1216. Assert.Equal (string.Empty, list [0]);
  1217. }
  1218. else
  1219. {
  1220. Assert.NotEqual (string.Empty, list [0]);
  1221. }
  1222. if (text.Contains ("\r\n") && maxWidth > 0)
  1223. {
  1224. Assert.Equal (
  1225. StringExtensions.ToString (text.ToRunes () [..expectedClippedWidth])
  1226. .Replace ("\r\n", " "),
  1227. list [0]
  1228. );
  1229. }
  1230. else if (text.Contains ('\n') && maxWidth > 0)
  1231. {
  1232. Assert.Equal (
  1233. StringExtensions.ToString (text.ToRunes () [..expectedClippedWidth])
  1234. .Replace ("\n", " "),
  1235. list [0]
  1236. );
  1237. }
  1238. else
  1239. {
  1240. Assert.Equal (StringExtensions.ToString (text.ToRunes () [..expectedClippedWidth]), list [0]);
  1241. }
  1242. }
  1243. [Theory]
  1244. [InlineData ("A sentence has words.\nLine 2.", 0, -29, Alignment.Start, false, 1, true, new [] { "" })]
  1245. [InlineData (
  1246. "A sentence has words.\nLine 2.",
  1247. 1,
  1248. -28,
  1249. Alignment.Start,
  1250. false,
  1251. 2,
  1252. false,
  1253. new [] { "A", "L" }
  1254. )]
  1255. [InlineData (
  1256. "A sentence has words.\nLine 2.",
  1257. 5,
  1258. -24,
  1259. Alignment.Start,
  1260. false,
  1261. 2,
  1262. false,
  1263. new [] { "A sen", "Line " }
  1264. )]
  1265. [InlineData (
  1266. "A sentence has words.\nLine 2.",
  1267. 28,
  1268. -1,
  1269. Alignment.Start,
  1270. false,
  1271. 2,
  1272. false,
  1273. new [] { "A sentence has words.", "Line 2." }
  1274. )]
  1275. //// no clip
  1276. [InlineData (
  1277. "A sentence has words.\nLine 2.",
  1278. 29,
  1279. 0,
  1280. Alignment.Start,
  1281. false,
  1282. 2,
  1283. false,
  1284. new [] { "A sentence has words.", "Line 2." }
  1285. )]
  1286. [InlineData (
  1287. "A sentence has words.\nLine 2.",
  1288. 30,
  1289. 1,
  1290. Alignment.Start,
  1291. false,
  1292. 2,
  1293. false,
  1294. new [] { "A sentence has words.", "Line 2." }
  1295. )]
  1296. [InlineData ("A sentence has words.\r\nLine 2.", 0, -30, Alignment.Start, false, 1, true, new [] { "" })]
  1297. [InlineData (
  1298. "A sentence has words.\r\nLine 2.",
  1299. 1,
  1300. -29,
  1301. Alignment.Start,
  1302. false,
  1303. 2,
  1304. false,
  1305. new [] { "A", "L" }
  1306. )]
  1307. [InlineData (
  1308. "A sentence has words.\r\nLine 2.",
  1309. 5,
  1310. -25,
  1311. Alignment.Start,
  1312. false,
  1313. 2,
  1314. false,
  1315. new [] { "A sen", "Line " }
  1316. )]
  1317. [InlineData (
  1318. "A sentence has words.\r\nLine 2.",
  1319. 29,
  1320. -1,
  1321. Alignment.Start,
  1322. false,
  1323. 2,
  1324. false,
  1325. new [] { "A sentence has words.", "Line 2." }
  1326. )]
  1327. [InlineData (
  1328. "A sentence has words.\r\nLine 2.",
  1329. 30,
  1330. 0,
  1331. Alignment.Start,
  1332. false,
  1333. 2,
  1334. false,
  1335. new [] { "A sentence has words.", "Line 2." }
  1336. )]
  1337. [InlineData (
  1338. "A sentence has words.\r\nLine 2.",
  1339. 31,
  1340. 1,
  1341. Alignment.Start,
  1342. false,
  1343. 2,
  1344. false,
  1345. new [] { "A sentence has words.", "Line 2." }
  1346. )]
  1347. public void Reformat_NoWordrap_NewLines_MultiLine_True (
  1348. string text,
  1349. int maxWidth,
  1350. int widthOffset,
  1351. Alignment alignment,
  1352. bool wrap,
  1353. int linesCount,
  1354. bool stringEmpty,
  1355. IEnumerable<string> resultLines
  1356. )
  1357. {
  1358. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  1359. List<string> list = TextFormatter.Format (
  1360. text,
  1361. maxWidth,
  1362. alignment,
  1363. wrap,
  1364. false,
  1365. 0,
  1366. TextDirection.LeftRight_TopBottom,
  1367. true
  1368. );
  1369. Assert.NotEmpty (list);
  1370. Assert.True (list.Count == linesCount);
  1371. if (stringEmpty)
  1372. {
  1373. Assert.Equal (string.Empty, list [0]);
  1374. }
  1375. else
  1376. {
  1377. Assert.NotEqual (string.Empty, list [0]);
  1378. }
  1379. Assert.Equal (list, resultLines);
  1380. }
  1381. [Theory]
  1382. [InlineData ("A sentence has words.\nLine 2.", 0, -29, Alignment.Start, false, 1, true, new [] { "" })]
  1383. [InlineData (
  1384. "A sentence has words.\nLine 2.",
  1385. 1,
  1386. -28,
  1387. Alignment.Start,
  1388. false,
  1389. 2,
  1390. false,
  1391. new [] { "A", "L" }
  1392. )]
  1393. [InlineData (
  1394. "A sentence has words.\nLine 2.",
  1395. 5,
  1396. -24,
  1397. Alignment.Start,
  1398. false,
  1399. 2,
  1400. false,
  1401. new [] { "A sen", "Line " }
  1402. )]
  1403. [InlineData (
  1404. "A sentence has words.\nLine 2.",
  1405. 28,
  1406. -1,
  1407. Alignment.Start,
  1408. false,
  1409. 2,
  1410. false,
  1411. new [] { "A sentence has words.", "Line 2." }
  1412. )]
  1413. //// no clip
  1414. [InlineData (
  1415. "A sentence has words.\nLine 2.",
  1416. 29,
  1417. 0,
  1418. Alignment.Start,
  1419. false,
  1420. 2,
  1421. false,
  1422. new [] { "A sentence has words.", "Line 2." }
  1423. )]
  1424. [InlineData (
  1425. "A sentence has words.\nLine 2.",
  1426. 30,
  1427. 1,
  1428. Alignment.Start,
  1429. false,
  1430. 2,
  1431. false,
  1432. new [] { "A sentence has words.", "Line 2." }
  1433. )]
  1434. [InlineData ("A sentence has words.\r\nLine 2.", 0, -30, Alignment.Start, false, 1, true, new [] { "" })]
  1435. [InlineData (
  1436. "A sentence has words.\r\nLine 2.",
  1437. 1,
  1438. -29,
  1439. Alignment.Start,
  1440. false,
  1441. 2,
  1442. false,
  1443. new [] { "A", "L" }
  1444. )]
  1445. [InlineData (
  1446. "A sentence has words.\r\nLine 2.",
  1447. 5,
  1448. -25,
  1449. Alignment.Start,
  1450. false,
  1451. 2,
  1452. false,
  1453. new [] { "A sen", "Line " }
  1454. )]
  1455. [InlineData (
  1456. "A sentence has words.\r\nLine 2.",
  1457. 29,
  1458. -1,
  1459. Alignment.Start,
  1460. false,
  1461. 2,
  1462. false,
  1463. new [] { "A sentence has words.", "Line 2." }
  1464. )]
  1465. [InlineData (
  1466. "A sentence has words.\r\nLine 2.",
  1467. 30,
  1468. 0,
  1469. Alignment.Start,
  1470. false,
  1471. 2,
  1472. false,
  1473. new [] { "A sentence has words.", "Line 2." }
  1474. )]
  1475. [InlineData (
  1476. "A sentence has words.\r\nLine 2.",
  1477. 31,
  1478. 1,
  1479. Alignment.Start,
  1480. false,
  1481. 2,
  1482. false,
  1483. new [] { "A sentence has words.", "Line 2." }
  1484. )]
  1485. public void Reformat_NoWordrap_NewLines_MultiLine_True_Vertical (
  1486. string text,
  1487. int maxWidth,
  1488. int widthOffset,
  1489. Alignment alignment,
  1490. bool wrap,
  1491. int linesCount,
  1492. bool stringEmpty,
  1493. IEnumerable<string> resultLines
  1494. )
  1495. {
  1496. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  1497. List<string> list = TextFormatter.Format (
  1498. text,
  1499. maxWidth,
  1500. alignment,
  1501. wrap,
  1502. false,
  1503. 0,
  1504. TextDirection.TopBottom_LeftRight,
  1505. true
  1506. );
  1507. Assert.NotEmpty (list);
  1508. Assert.True (list.Count == linesCount);
  1509. if (stringEmpty)
  1510. {
  1511. Assert.Equal (string.Empty, list [0]);
  1512. }
  1513. else
  1514. {
  1515. Assert.NotEqual (string.Empty, list [0]);
  1516. }
  1517. Assert.Equal (list, resultLines);
  1518. }
  1519. [Theory]
  1520. [InlineData ("", 0, 0, Alignment.Start, false, 1, true)]
  1521. [InlineData ("", 1, 1, Alignment.Start, false, 1, true)]
  1522. [InlineData ("A sentence has words.", 0, -21, Alignment.Start, false, 1, true)]
  1523. [InlineData ("A sentence has words.", 1, -20, Alignment.Start, false, 1, false)]
  1524. [InlineData ("A sentence has words.", 5, -16, Alignment.Start, false, 1, false)]
  1525. [InlineData ("A sentence has words.", 20, -1, Alignment.Start, false, 1, false)]
  1526. // no clip
  1527. [InlineData ("A sentence has words.", 21, 0, Alignment.Start, false, 1, false)]
  1528. [InlineData ("A sentence has words.", 22, 1, Alignment.Start, false, 1, false)]
  1529. public void Reformat_NoWordrap_SingleLine (
  1530. string text,
  1531. int maxWidth,
  1532. int widthOffset,
  1533. Alignment alignment,
  1534. bool wrap,
  1535. int linesCount,
  1536. bool stringEmpty
  1537. )
  1538. {
  1539. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  1540. int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
  1541. List<string> list = TextFormatter.Format (text, maxWidth, alignment, wrap);
  1542. Assert.NotEmpty (list);
  1543. Assert.True (list.Count == linesCount);
  1544. if (stringEmpty)
  1545. {
  1546. Assert.Equal (string.Empty, list [0]);
  1547. }
  1548. else
  1549. {
  1550. Assert.NotEqual (string.Empty, list [0]);
  1551. }
  1552. Assert.Equal (StringExtensions.ToString (text.ToRunes () [..expectedClippedWidth]), list [0]);
  1553. }
  1554. [Theory]
  1555. // Unicode
  1556. [InlineData (
  1557. "\u2460\u2461\u2462\n\u2460\u2461\u2462\u2463\u2464",
  1558. 8,
  1559. -1,
  1560. Alignment.Start,
  1561. true,
  1562. false,
  1563. new [] { "\u2460\u2461\u2462", "\u2460\u2461\u2462\u2463\u2464" }
  1564. )]
  1565. // no clip
  1566. [InlineData (
  1567. "\u2460\u2461\u2462\n\u2460\u2461\u2462\u2463\u2464",
  1568. 9,
  1569. 0,
  1570. Alignment.Start,
  1571. true,
  1572. false,
  1573. new [] { "\u2460\u2461\u2462", "\u2460\u2461\u2462\u2463\u2464" }
  1574. )]
  1575. [InlineData (
  1576. "\u2460\u2461\u2462\n\u2460\u2461\u2462\u2463\u2464",
  1577. 10,
  1578. 1,
  1579. Alignment.Start,
  1580. true,
  1581. false,
  1582. new [] { "\u2460\u2461\u2462", "\u2460\u2461\u2462\u2463\u2464" }
  1583. )]
  1584. public void Reformat_Unicode_Wrap_Spaces_NewLines (
  1585. string text,
  1586. int maxWidth,
  1587. int widthOffset,
  1588. Alignment alignment,
  1589. bool wrap,
  1590. bool preserveTrailingSpaces,
  1591. IEnumerable<string> resultLines
  1592. )
  1593. {
  1594. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  1595. List<string> list = TextFormatter.Format (text, maxWidth, alignment, wrap, preserveTrailingSpaces);
  1596. Assert.Equal (list.Count, resultLines.Count ());
  1597. Assert.Equal (resultLines, list);
  1598. }
  1599. [Theory]
  1600. // Unicode
  1601. // Even # of chars
  1602. // 0123456789
  1603. [InlineData ("\u2660пÑРвРÑ", 10, -1, Alignment.Start, true, false, new [] { "\u2660пÑРвÐ", "Ñ" })]
  1604. // no clip
  1605. [InlineData ("\u2660пÑРвРÑ", 11, 0, Alignment.Start, true, false, new [] { "\u2660пÑРвРÑ" })]
  1606. [InlineData ("\u2660пÑРвРÑ", 12, 1, Alignment.Start, true, false, new [] { "\u2660пÑРвРÑ" })]
  1607. // Unicode
  1608. // Odd # of chars
  1609. // 0123456789
  1610. [InlineData ("\u2660 ÑРвРÑ", 9, -1, Alignment.Start, true, false, new [] { "\u2660 ÑРвÐ", "Ñ" })]
  1611. // no clip
  1612. [InlineData ("\u2660 ÑРвРÑ", 10, 0, Alignment.Start, true, false, new [] { "\u2660 ÑРвРÑ" })]
  1613. [InlineData ("\u2660 ÑРвРÑ", 11, 1, Alignment.Start, true, false, new [] { "\u2660 ÑРвРÑ" })]
  1614. public void Reformat_Unicode_Wrap_Spaces_No_NewLines (
  1615. string text,
  1616. int maxWidth,
  1617. int widthOffset,
  1618. Alignment alignment,
  1619. bool wrap,
  1620. bool preserveTrailingSpaces,
  1621. IEnumerable<string> resultLines
  1622. )
  1623. {
  1624. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  1625. List<string> list = TextFormatter.Format (text, maxWidth, alignment, wrap, preserveTrailingSpaces);
  1626. Assert.Equal (list.Count, resultLines.Count ());
  1627. Assert.Equal (resultLines, list);
  1628. }
  1629. [Theory]
  1630. // Even # of spaces
  1631. // 0123456789
  1632. [InlineData ("012 456 89", 0, -10, Alignment.Start, true, true, true, new [] { "" })]
  1633. [InlineData (
  1634. "012 456 89",
  1635. 1,
  1636. -9,
  1637. Alignment.Start,
  1638. true,
  1639. true,
  1640. false,
  1641. new [] { "0", "1", "2", " ", "4", "5", "6", " ", "8", "9" },
  1642. "01245689"
  1643. )]
  1644. [InlineData ("012 456 89", 5, -5, Alignment.Start, true, true, false, new [] { "012 ", "456 ", "89" })]
  1645. [InlineData ("012 456 89", 9, -1, Alignment.Start, true, true, false, new [] { "012 456 ", "89" })]
  1646. // no clip
  1647. [InlineData ("012 456 89", 10, 0, Alignment.Start, true, true, false, new [] { "012 456 89" })]
  1648. [InlineData ("012 456 89", 11, 1, Alignment.Start, true, true, false, new [] { "012 456 89" })]
  1649. // Odd # of spaces
  1650. // 01234567890123
  1651. [InlineData ("012 456 89 end", 13, -1, Alignment.Start, true, true, false, new [] { "012 456 89 ", "end" })]
  1652. // no clip
  1653. [InlineData ("012 456 89 end", 14, 0, Alignment.Start, true, true, false, new [] { "012 456 89 end" })]
  1654. [InlineData ("012 456 89 end", 15, 1, Alignment.Start, true, true, false, new [] { "012 456 89 end" })]
  1655. public void Reformat_Wrap_Spaces_No_NewLines (
  1656. string text,
  1657. int maxWidth,
  1658. int widthOffset,
  1659. Alignment alignment,
  1660. bool wrap,
  1661. bool preserveTrailingSpaces,
  1662. bool stringEmpty,
  1663. IEnumerable<string> resultLines,
  1664. string noSpaceText = ""
  1665. )
  1666. {
  1667. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  1668. int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
  1669. List<string> list = TextFormatter.Format (text, maxWidth, alignment, wrap, preserveTrailingSpaces);
  1670. Assert.NotEmpty (list);
  1671. Assert.True (list.Count == resultLines.Count ());
  1672. if (stringEmpty)
  1673. {
  1674. Assert.Equal (string.Empty, list [0]);
  1675. }
  1676. else
  1677. {
  1678. Assert.NotEqual (string.Empty, list [0]);
  1679. }
  1680. Assert.Equal (resultLines, list);
  1681. if (maxWidth > 0)
  1682. {
  1683. // remove whitespace chars
  1684. if (maxWidth < 5)
  1685. {
  1686. expectedClippedWidth = text.GetRuneCount () - text.Sum (r => r == ' ' ? 1 : 0);
  1687. }
  1688. else
  1689. {
  1690. expectedClippedWidth = Math.Min (
  1691. text.GetRuneCount (),
  1692. maxWidth - text.Sum (r => r == ' ' ? 1 : 0)
  1693. );
  1694. }
  1695. list = TextFormatter.Format (text, maxWidth, Alignment.Start, wrap);
  1696. if (maxWidth == 1)
  1697. {
  1698. Assert.Equal (expectedClippedWidth, list.Count);
  1699. Assert.Equal (noSpaceText, string.Concat (list.ToArray ()));
  1700. }
  1701. if (maxWidth > 1 && maxWidth < 10)
  1702. {
  1703. Assert.Equal (
  1704. StringExtensions.ToString (text.ToRunes () [..expectedClippedWidth]),
  1705. list [0]
  1706. );
  1707. }
  1708. }
  1709. }
  1710. [Theory]
  1711. [InlineData (null)]
  1712. [InlineData ("")]
  1713. [InlineData ("a")]
  1714. public void RemoveHotKeySpecifier_InValid_ReturnsOriginal (string text)
  1715. {
  1716. var hotKeySpecifier = (Rune)'_';
  1717. if (text == null)
  1718. {
  1719. Assert.Null (TextFormatter.RemoveHotKeySpecifier (text, 0, hotKeySpecifier));
  1720. Assert.Null (TextFormatter.RemoveHotKeySpecifier (text, -1, hotKeySpecifier));
  1721. Assert.Null (TextFormatter.RemoveHotKeySpecifier (text, 100, hotKeySpecifier));
  1722. }
  1723. else
  1724. {
  1725. Assert.Equal (text, TextFormatter.RemoveHotKeySpecifier (text, 0, hotKeySpecifier));
  1726. Assert.Equal (text, TextFormatter.RemoveHotKeySpecifier (text, -1, hotKeySpecifier));
  1727. Assert.Equal (text, TextFormatter.RemoveHotKeySpecifier (text, 100, hotKeySpecifier));
  1728. }
  1729. }
  1730. [Theory]
  1731. [InlineData ("all lower case", 0)]
  1732. [InlineData ("K Before", 0)]
  1733. [InlineData ("aK Second", 1)]
  1734. [InlineData ("Last K", 5)]
  1735. [InlineData ("fter K", 7)]
  1736. [InlineData ("Multiple K and R", 9)]
  1737. [InlineData ("Non-english: Кдать", 13)]
  1738. public void RemoveHotKeySpecifier_Valid_Legacy_ReturnsOriginal (string text, int hotPos)
  1739. {
  1740. var hotKeySpecifier = (Rune)'_';
  1741. Assert.Equal (text, TextFormatter.RemoveHotKeySpecifier (text, hotPos, hotKeySpecifier));
  1742. }
  1743. [Theory]
  1744. [InlineData ("_K Before", 0, "K Before")]
  1745. [InlineData ("a_K Second", 1, "aK Second")]
  1746. [InlineData ("Last _K", 5, "Last K")]
  1747. [InlineData ("After K_", 7, "After K")]
  1748. [InlineData ("Multiple _K and _R", 9, "Multiple K and _R")]
  1749. [InlineData ("Non-english: _Кдать", 13, "Non-english: Кдать")]
  1750. public void RemoveHotKeySpecifier_Valid_ReturnsStripped (string text, int hotPos, string expectedText)
  1751. {
  1752. var hotKeySpecifier = (Rune)'_';
  1753. Assert.Equal (expectedText, TextFormatter.RemoveHotKeySpecifier (text, hotPos, hotKeySpecifier));
  1754. }
  1755. [Theory]
  1756. [InlineData ("test", 0, 't', "test")]
  1757. [InlineData ("test", 1, 'e', "test")]
  1758. [InlineData ("Ok", 0, 'O', "Ok")]
  1759. [InlineData ("[◦ Ok ◦]", 3, 'O', "[◦ Ok ◦]")]
  1760. [InlineData ("^k", 0, '^', "^k")]
  1761. public void ReplaceHotKeyWithTag (string text, int hotPos, uint tag, string expected)
  1762. {
  1763. var tf = new TextFormatter ();
  1764. List<Rune> runes = text.ToRuneList ();
  1765. Rune rune;
  1766. if (Rune.TryGetRuneAt (text, hotPos, out rune))
  1767. {
  1768. Assert.Equal (rune, (Rune)tag);
  1769. }
  1770. string result = TextFormatter.ReplaceHotKeyWithTag (text, hotPos);
  1771. Assert.Equal (result, expected);
  1772. Assert.Equal ((Rune)tag, result.ToRunes () [hotPos]);
  1773. Assert.Equal (text.GetRuneCount (), runes.Count);
  1774. Assert.Equal (text, StringExtensions.ToString (runes));
  1775. }
  1776. [Theory]
  1777. [MemberData (nameof (SplitEnvironmentNewLine))]
  1778. public void SplitNewLine_Ending__With_Or_Without_NewLine_Probably_CRLF (
  1779. string text,
  1780. IEnumerable<string> expected
  1781. )
  1782. {
  1783. List<string> splited = TextFormatter.SplitNewLine (text);
  1784. Assert.Equal (expected, splited);
  1785. }
  1786. [Theory]
  1787. [InlineData (
  1788. "First Line 界\nSecond Line 界\nThird Line 界\n",
  1789. new [] { "First Line 界", "Second Line 界", "Third Line 界", "" }
  1790. )]
  1791. public void SplitNewLine_Ending_With_NewLine_Only_LF (string text, IEnumerable<string> expected)
  1792. {
  1793. List<string> splited = TextFormatter.SplitNewLine (text);
  1794. Assert.Equal (expected, splited);
  1795. }
  1796. [Theory]
  1797. [InlineData (
  1798. "First Line 界\nSecond Line 界\nThird Line 界",
  1799. new [] { "First Line 界", "Second Line 界", "Third Line 界" }
  1800. )]
  1801. public void SplitNewLine_Ending_Without_NewLine_Only_LF (string text, IEnumerable<string> expected)
  1802. {
  1803. List<string> splited = TextFormatter.SplitNewLine (text);
  1804. Assert.Equal (expected, splited);
  1805. }
  1806. [Theory]
  1807. [InlineData ("New Test 你", 10, 10, 20320, 20320, 9, "你")]
  1808. [InlineData ("New Test \U0001d539", 10, 11, 120121, 55349, 9, "𝔹")]
  1809. public void String_Array_Is_Not_Always_Equal_ToRunes_Array (
  1810. string text,
  1811. int runesLength,
  1812. int stringLength,
  1813. int runeValue,
  1814. int stringValue,
  1815. int index,
  1816. string expected
  1817. )
  1818. {
  1819. Rune [] usToRunes = text.ToRunes ();
  1820. Assert.Equal (runesLength, usToRunes.Length);
  1821. Assert.Equal (stringLength, text.Length);
  1822. Assert.Equal (runeValue, usToRunes [index].Value);
  1823. Assert.Equal (stringValue, text [index]);
  1824. Assert.Equal (expected, usToRunes [index].ToString ());
  1825. if (char.IsHighSurrogate (text [index]))
  1826. {
  1827. // Rune array length isn't equal to string array
  1828. Assert.Equal (expected, new (new [] { text [index], text [index + 1] }));
  1829. }
  1830. else
  1831. {
  1832. // Rune array length is equal to string array
  1833. Assert.Equal (expected, text [index].ToString ());
  1834. }
  1835. }
  1836. [Theory]
  1837. [InlineData (17, 1, TextDirection.LeftRight_TopBottom, 4, "This is a Tab")]
  1838. [InlineData (1, 17, TextDirection.TopBottom_LeftRight, 4, "T\nh\ni\ns\n \ni\ns\n \na\n \n \n \n \n \nT\na\nb")]
  1839. [InlineData (13, 1, TextDirection.LeftRight_TopBottom, 0, "This is a Tab")]
  1840. [InlineData (1, 13, TextDirection.TopBottom_LeftRight, 0, "T\nh\ni\ns\n \ni\ns\n \na\n \nT\na\nb")]
  1841. public void TabWith_PreserveTrailingSpaces_False (
  1842. int width,
  1843. int height,
  1844. TextDirection textDirection,
  1845. int tabWidth,
  1846. string expected
  1847. )
  1848. {
  1849. var driver = new FakeDriver ();
  1850. driver.Init ();
  1851. var text = "This is a \tTab";
  1852. var tf = new TextFormatter ();
  1853. tf.Direction = textDirection;
  1854. tf.TabWidth = tabWidth;
  1855. tf.Text = text;
  1856. tf.ConstrainToWidth = 20;
  1857. tf.ConstrainToHeight = 20;
  1858. Assert.True (tf.WordWrap);
  1859. Assert.False (tf.PreserveTrailingSpaces);
  1860. tf.Draw (
  1861. new (0, 0, width, height),
  1862. new (ColorName.White, ColorName.Black),
  1863. new (ColorName.Blue, ColorName.Black),
  1864. default (Rectangle),
  1865. driver
  1866. );
  1867. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output, driver);
  1868. driver.End ();
  1869. }
  1870. [Theory]
  1871. [InlineData (17, 1, TextDirection.LeftRight_TopBottom, 4, "This is a Tab")]
  1872. [InlineData (1, 17, TextDirection.TopBottom_LeftRight, 4, "T\nh\ni\ns\n \ni\ns\n \na\n \n \n \n \n \nT\na\nb")]
  1873. [InlineData (13, 1, TextDirection.LeftRight_TopBottom, 0, "This is a Tab")]
  1874. [InlineData (1, 13, TextDirection.TopBottom_LeftRight, 0, "T\nh\ni\ns\n \ni\ns\n \na\n \nT\na\nb")]
  1875. public void TabWith_PreserveTrailingSpaces_True (
  1876. int width,
  1877. int height,
  1878. TextDirection textDirection,
  1879. int tabWidth,
  1880. string expected
  1881. )
  1882. {
  1883. var driver = new FakeDriver ();
  1884. driver.Init ();
  1885. var text = "This is a \tTab";
  1886. var tf = new TextFormatter ();
  1887. tf.Direction = textDirection;
  1888. tf.TabWidth = tabWidth;
  1889. tf.PreserveTrailingSpaces = true;
  1890. tf.Text = text;
  1891. tf.ConstrainToWidth = 20;
  1892. tf.ConstrainToHeight = 20;
  1893. Assert.True (tf.WordWrap);
  1894. tf.Draw (
  1895. new (0, 0, width, height),
  1896. new (ColorName.White, ColorName.Black),
  1897. new (ColorName.Blue, ColorName.Black),
  1898. default (Rectangle),
  1899. driver
  1900. );
  1901. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output, driver);
  1902. driver.End ();
  1903. }
  1904. [Theory]
  1905. [InlineData (17, 1, TextDirection.LeftRight_TopBottom, 4, "This is a Tab")]
  1906. [InlineData (1, 17, TextDirection.TopBottom_LeftRight, 4, "T\nh\ni\ns\n \ni\ns\n \na\n \n \n \n \n \nT\na\nb")]
  1907. [InlineData (13, 1, TextDirection.LeftRight_TopBottom, 0, "This is a Tab")]
  1908. [InlineData (1, 13, TextDirection.TopBottom_LeftRight, 0, "T\nh\ni\ns\n \ni\ns\n \na\n \nT\na\nb")]
  1909. public void TabWith_WordWrap_True (
  1910. int width,
  1911. int height,
  1912. TextDirection textDirection,
  1913. int tabWidth,
  1914. string expected
  1915. )
  1916. {
  1917. var driver = new FakeDriver ();
  1918. driver.Init ();
  1919. var text = "This is a \tTab";
  1920. var tf = new TextFormatter ();
  1921. tf.Direction = textDirection;
  1922. tf.TabWidth = tabWidth;
  1923. tf.WordWrap = true;
  1924. tf.Text = text;
  1925. tf.ConstrainToWidth = 20;
  1926. tf.ConstrainToHeight = 20;
  1927. Assert.False (tf.PreserveTrailingSpaces);
  1928. tf.Draw (
  1929. new (0, 0, width, height),
  1930. new (ColorName.White, ColorName.Black),
  1931. new (ColorName.Blue, ColorName.Black),
  1932. default (Rectangle),
  1933. driver
  1934. );
  1935. TestHelpers.AssertDriverContentsWithFrameAre (expected, _output, driver);
  1936. driver.End ();
  1937. }
  1938. [Theory]
  1939. [InlineData ("123456789", 3, "123")]
  1940. [InlineData ("Hello World", 8, "Hello Wo")]
  1941. public void TestClipOrPad_LongWord (string text, int fillPad, string expectedText)
  1942. {
  1943. // word is long but we want it to fill # space only
  1944. Assert.Equal (expectedText, TextFormatter.ClipOrPad (text, fillPad));
  1945. }
  1946. [Theory]
  1947. [InlineData ("fff", 6, "fff ")]
  1948. [InlineData ("Hello World", 16, "Hello World ")]
  1949. public void TestClipOrPad_ShortWord (string text, int fillPad, string expectedText)
  1950. {
  1951. // word is short but we want it to fill # so it should be padded
  1952. Assert.Equal (expectedText, TextFormatter.ClipOrPad (text, fillPad));
  1953. }
  1954. [Theory]
  1955. [InlineData ("你", TextDirection.LeftRight_TopBottom, 2, 1)]
  1956. [InlineData ("你", TextDirection.TopBottom_LeftRight, 2, 1)]
  1957. [InlineData ("你你", TextDirection.LeftRight_TopBottom, 4, 1)]
  1958. [InlineData ("你你", TextDirection.TopBottom_LeftRight, 2, 2)]
  1959. public void Text_Set_SizeIsCorrect (string text, TextDirection textDirection, int expectedWidth, int expectedHeight)
  1960. {
  1961. var tf = new TextFormatter { Direction = textDirection, Text = text };
  1962. tf.ConstrainToWidth = 10;
  1963. tf.ConstrainToHeight = 10;
  1964. Assert.Equal (new (expectedWidth, expectedHeight), tf.FormatAndGetSize ());
  1965. }
  1966. [Fact]
  1967. public void WordWrap_BigWidth ()
  1968. {
  1969. List<string> wrappedLines;
  1970. var text = "Constantinople";
  1971. wrappedLines = TextFormatter.WordWrapText (text, 100);
  1972. Assert.True (wrappedLines.Count == 1);
  1973. Assert.Equal ("Constantinople", wrappedLines [0]);
  1974. }
  1975. [Fact]
  1976. public void WordWrap_Invalid ()
  1977. {
  1978. var text = string.Empty;
  1979. var width = 0;
  1980. Assert.Empty (TextFormatter.WordWrapText (null, width));
  1981. Assert.Empty (TextFormatter.WordWrapText (text, width));
  1982. Assert.Throws<ArgumentOutOfRangeException> (() => TextFormatter.WordWrapText (text, -1));
  1983. }
  1984. [Theory]
  1985. [InlineData ("A sentence has words.", 3, -18, new [] { "A", "sen", "ten", "ce", "has", "wor", "ds." })]
  1986. [InlineData (
  1987. "A sentence has words.",
  1988. 2,
  1989. -19,
  1990. new [] { "A", "se", "nt", "en", "ce", "ha", "s", "wo", "rd", "s." }
  1991. )]
  1992. [InlineData (
  1993. "A sentence has words.",
  1994. 1,
  1995. -20,
  1996. new [] { "A", "s", "e", "n", "t", "e", "n", "c", "e", "h", "a", "s", "w", "o", "r", "d", "s", "." }
  1997. )]
  1998. public void WordWrap_Narrow_Default (
  1999. string text,
  2000. int maxWidth,
  2001. int widthOffset,
  2002. IEnumerable<string> resultLines
  2003. )
  2004. {
  2005. // Calls WordWrapText (text, width) and thus preserveTrailingSpaces defaults to false
  2006. List<string> wrappedLines;
  2007. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  2008. int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
  2009. wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
  2010. Assert.Equal (wrappedLines.Count, resultLines.Count ());
  2011. Assert.True (
  2012. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
  2013. );
  2014. Assert.True (
  2015. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
  2016. );
  2017. Assert.Equal (resultLines, wrappedLines);
  2018. }
  2019. [Theory]
  2020. [InlineData ("A sentence has words.", 21, 0, new [] { "A sentence has words." })]
  2021. [InlineData ("A sentence has words.", 20, -1, new [] { "A sentence has", "words." })]
  2022. [InlineData ("A sentence has words.", 15, -6, new [] { "A sentence has", "words." })]
  2023. [InlineData ("A sentence has words.", 14, -7, new [] { "A sentence has", "words." })]
  2024. [InlineData ("A sentence has words.", 13, -8, new [] { "A sentence", "has words." })]
  2025. // Unicode
  2026. [InlineData (
  2027. "A Unicode sentence (пÑивеÑ) has words.",
  2028. 42,
  2029. 0,
  2030. new [] { "A Unicode sentence (пÑивеÑ) has words." }
  2031. )]
  2032. [InlineData (
  2033. "A Unicode sentence (пÑивеÑ) has words.",
  2034. 41,
  2035. -1,
  2036. new [] { "A Unicode sentence (пÑивеÑ) has", "words." }
  2037. )]
  2038. [InlineData (
  2039. "A Unicode sentence (пÑивеÑ) has words.",
  2040. 36,
  2041. -6,
  2042. new [] { "A Unicode sentence (пÑивеÑ) has", "words." }
  2043. )]
  2044. [InlineData (
  2045. "A Unicode sentence (пÑивеÑ) has words.",
  2046. 35,
  2047. -7,
  2048. new [] { "A Unicode sentence (пÑивеÑ) has", "words." }
  2049. )]
  2050. [InlineData (
  2051. "A Unicode sentence (пÑивеÑ) has words.",
  2052. 34,
  2053. -8,
  2054. new [] { "A Unicode sentence (пÑивеÑ)", "has words." }
  2055. )]
  2056. [InlineData (
  2057. "A Unicode sentence (пÑивеÑ) has words.",
  2058. 25,
  2059. -17,
  2060. new [] { "A Unicode sentence", "(пÑивеÑ) has words." }
  2061. )]
  2062. public void WordWrap_NoNewLines_Default (
  2063. string text,
  2064. int maxWidth,
  2065. int widthOffset,
  2066. IEnumerable<string> resultLines
  2067. )
  2068. {
  2069. // Calls WordWrapText (text, width) and thus preserveTrailingSpaces defaults to false
  2070. List<string> wrappedLines;
  2071. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  2072. int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
  2073. wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
  2074. Assert.Equal (wrappedLines.Count, resultLines.Count ());
  2075. Assert.True (
  2076. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
  2077. );
  2078. Assert.True (
  2079. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
  2080. );
  2081. Assert.Equal (resultLines, wrappedLines);
  2082. }
  2083. [Theory]
  2084. [InlineData ("これが最初の行です。 こんにちは世界。 これが2行目です。", 29, 0, new [] { "これが最初の行です。", "こんにちは世界。", "これが2行目です。" })]
  2085. public void WordWrap_PreserveTrailingSpaces_False_Unicode_Wide_Runes (
  2086. string text,
  2087. int maxWidth,
  2088. int widthOffset,
  2089. IEnumerable<string> resultLines
  2090. )
  2091. {
  2092. List<string> wrappedLines;
  2093. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  2094. int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
  2095. wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
  2096. Assert.Equal (wrappedLines.Count, resultLines.Count ());
  2097. Assert.True (
  2098. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
  2099. );
  2100. Assert.True (
  2101. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
  2102. );
  2103. Assert.Equal (resultLines, wrappedLines);
  2104. }
  2105. [Theory]
  2106. [InlineData ("文に は言葉 があり ます。", 14, 0, new [] { "文に は言葉", "があり ます。" })]
  2107. [InlineData ("文に は言葉 があり ます。", 3, -11, new [] { "文", "に", "は", "言", "葉", "が", "あ", "り", "ま", "す", "。" })]
  2108. [InlineData ("文に は言葉 があり ます。", 2, -12, new [] { "文", "に", "は", "言", "葉", "が", "あ", "り", "ま", "す", "。" })]
  2109. [InlineData (
  2110. "文に は言葉 があり ます。",
  2111. 1,
  2112. -13,
  2113. new [] { " ", " ", " " }
  2114. )] // Just Spaces; should result in a single space for each line
  2115. public void WordWrap_PreserveTrailingSpaces_False_Wide_Runes (
  2116. string text,
  2117. int maxWidth,
  2118. int widthOffset,
  2119. IEnumerable<string> resultLines
  2120. )
  2121. {
  2122. List<string> wrappedLines;
  2123. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  2124. int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
  2125. wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
  2126. Assert.Equal (wrappedLines.Count, resultLines.Count ());
  2127. Assert.True (
  2128. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
  2129. );
  2130. Assert.True (
  2131. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
  2132. );
  2133. Assert.Equal (resultLines, wrappedLines);
  2134. }
  2135. [Theory]
  2136. [InlineData (null, 1, new string [] { })] // null input
  2137. [InlineData ("", 1, new string [] { })] // Empty input
  2138. [InlineData ("1 34", 1, new [] { "1", "3", "4" })] // Single Spaces
  2139. [InlineData ("1", 1, new [] { "1" })] // Short input
  2140. [InlineData ("12", 1, new [] { "1", "2" })]
  2141. [InlineData ("123", 1, new [] { "1", "2", "3" })]
  2142. [InlineData ("123456", 1, new [] { "1", "2", "3", "4", "5", "6" })] // No spaces
  2143. [InlineData (" ", 1, new [] { " " })] // Just Spaces; should result in a single space
  2144. [InlineData (" ", 1, new [] { " " })]
  2145. [InlineData (" ", 1, new [] { " ", " " })]
  2146. [InlineData (" ", 1, new [] { " ", " " })]
  2147. [InlineData ("12 456", 1, new [] { "1", "2", "4", "5", "6" })] // Single Spaces
  2148. [InlineData (" 2 456", 1, new [] { " ", "2", "4", "5", "6" })] // Leading spaces should be preserved.
  2149. [InlineData (" 2 456 8", 1, new [] { " ", "2", "4", "5", "6", "8" })]
  2150. [InlineData (
  2151. "A sentence has words. ",
  2152. 1,
  2153. new [] { "A", "s", "e", "n", "t", "e", "n", "c", "e", "h", "a", "s", "w", "o", "r", "d", "s", "." }
  2154. )] // Complex example
  2155. [InlineData ("12 567", 1, new [] { "1", "2", " ", "5", "6", "7" })] // Double Spaces
  2156. [InlineData (" 3 567", 1, new [] { " ", "3", "5", "6", "7" })] // Double Leading spaces should be preserved.
  2157. [InlineData (" 3 678 1", 1, new [] { " ", "3", " ", "6", "7", "8", " ", "1" })]
  2158. [InlineData ("1 456", 1, new [] { "1", " ", "4", "5", "6" })]
  2159. [InlineData (
  2160. "A sentence has words. ",
  2161. 1,
  2162. new []
  2163. {
  2164. "A", " ", "s", "e", "n", "t", "e", "n", "c", "e", " ", "h", "a", "s", "w", "o", "r", "d", "s", ".", " "
  2165. }
  2166. )] // Double space Complex example
  2167. public void WordWrap_PreserveTrailingSpaces_False_With_Simple_Runes_Width_1 (
  2168. string text,
  2169. int width,
  2170. IEnumerable<string> resultLines
  2171. )
  2172. {
  2173. List<string> wrappedLines = TextFormatter.WordWrapText (text, width);
  2174. Assert.Equal (wrappedLines.Count, resultLines.Count ());
  2175. Assert.Equal (resultLines, wrappedLines);
  2176. var breakLines = "";
  2177. foreach (string line in wrappedLines)
  2178. {
  2179. breakLines += $"{line}{Environment.NewLine}";
  2180. }
  2181. var expected = string.Empty;
  2182. foreach (string line in resultLines)
  2183. {
  2184. expected += $"{line}{Environment.NewLine}";
  2185. }
  2186. Assert.Equal (expected, breakLines);
  2187. }
  2188. [Theory]
  2189. [InlineData (null, 3, new string [] { })] // null input
  2190. [InlineData ("", 3, new string [] { })] // Empty input
  2191. [InlineData ("1", 3, new [] { "1" })] // Short input
  2192. [InlineData ("12", 3, new [] { "12" })]
  2193. [InlineData ("123", 3, new [] { "123" })]
  2194. [InlineData ("123456", 3, new [] { "123", "456" })] // No spaces
  2195. [InlineData ("1234567", 3, new [] { "123", "456", "7" })] // No spaces
  2196. [InlineData (" ", 3, new [] { " " })] // Just Spaces; should result in a single space
  2197. [InlineData (" ", 3, new [] { " " })]
  2198. [InlineData (" ", 3, new [] { " " })]
  2199. [InlineData (" ", 3, new [] { " " })]
  2200. [InlineData ("12 456", 3, new [] { "12", "456" })] // Single Spaces
  2201. [InlineData (" 2 456", 3, new [] { " 2", "456" })] // Leading spaces should be preserved.
  2202. [InlineData (" 2 456 8", 3, new [] { " 2", "456", "8" })]
  2203. [InlineData (
  2204. "A sentence has words. ",
  2205. 3,
  2206. new [] { "A", "sen", "ten", "ce", "has", "wor", "ds." }
  2207. )] // Complex example
  2208. [InlineData ("12 567", 3, new [] { "12 ", "567" })] // Double Spaces
  2209. [InlineData (" 3 567", 3, new [] { " 3", "567" })] // Double Leading spaces should be preserved.
  2210. [InlineData (" 3 678 1", 3, new [] { " 3", " 67", "8 ", "1" })]
  2211. [InlineData ("1 456", 3, new [] { "1 ", "456" })]
  2212. [InlineData (
  2213. "A sentence has words. ",
  2214. 3,
  2215. new [] { "A ", "sen", "ten", "ce ", " ", "has", "wor", "ds.", " " }
  2216. )] // Double space Complex example
  2217. public void WordWrap_PreserveTrailingSpaces_False_With_Simple_Runes_Width_3 (
  2218. string text,
  2219. int width,
  2220. IEnumerable<string> resultLines
  2221. )
  2222. {
  2223. List<string> wrappedLines = TextFormatter.WordWrapText (text, width);
  2224. Assert.Equal (wrappedLines.Count, resultLines.Count ());
  2225. Assert.Equal (resultLines, wrappedLines);
  2226. var breakLines = "";
  2227. foreach (string line in wrappedLines)
  2228. {
  2229. breakLines += $"{line}{Environment.NewLine}";
  2230. }
  2231. var expected = string.Empty;
  2232. foreach (string line in resultLines)
  2233. {
  2234. expected += $"{line}{Environment.NewLine}";
  2235. }
  2236. Assert.Equal (expected, breakLines);
  2237. }
  2238. [Theory]
  2239. [InlineData (null, 50, new string [] { })] // null input
  2240. [InlineData ("", 50, new string [] { })] // Empty input
  2241. [InlineData ("1", 50, new [] { "1" })] // Short input
  2242. [InlineData ("12", 50, new [] { "12" })]
  2243. [InlineData ("123", 50, new [] { "123" })]
  2244. [InlineData ("123456", 50, new [] { "123456" })] // No spaces
  2245. [InlineData ("1234567", 50, new [] { "1234567" })] // No spaces
  2246. [InlineData (" ", 50, new [] { " " })] // Just Spaces; should result in a single space
  2247. [InlineData (" ", 50, new [] { " " })]
  2248. [InlineData (" ", 50, new [] { " " })]
  2249. [InlineData ("12 456", 50, new [] { "12 456" })] // Single Spaces
  2250. [InlineData (" 2 456", 50, new [] { " 2 456" })] // Leading spaces should be preserved.
  2251. [InlineData (" 2 456 8", 50, new [] { " 2 456 8" })]
  2252. [InlineData ("A sentence has words. ", 50, new [] { "A sentence has words. " })] // Complex example
  2253. [InlineData ("12 567", 50, new [] { "12 567" })] // Double Spaces
  2254. [InlineData (" 3 567", 50, new [] { " 3 567" })] // Double Leading spaces should be preserved.
  2255. [InlineData (" 3 678 1", 50, new [] { " 3 678 1" })]
  2256. [InlineData ("1 456", 50, new [] { "1 456" })]
  2257. [InlineData (
  2258. "A sentence has words. ",
  2259. 50,
  2260. new [] { "A sentence has words. " }
  2261. )] // Double space Complex example
  2262. public void WordWrap_PreserveTrailingSpaces_False_With_Simple_Runes_Width_50 (
  2263. string text,
  2264. int width,
  2265. IEnumerable<string> resultLines
  2266. )
  2267. {
  2268. List<string> wrappedLines = TextFormatter.WordWrapText (text, width);
  2269. Assert.Equal (wrappedLines.Count, resultLines.Count ());
  2270. Assert.Equal (resultLines, wrappedLines);
  2271. var breakLines = "";
  2272. foreach (string line in wrappedLines)
  2273. {
  2274. breakLines += $"{line}{Environment.NewLine}";
  2275. }
  2276. var expected = string.Empty;
  2277. foreach (string line in resultLines)
  2278. {
  2279. expected += $"{line}{Environment.NewLine}";
  2280. }
  2281. Assert.Equal (expected, breakLines);
  2282. }
  2283. [Theory]
  2284. [InlineData ("A sentence has words.", 14, -7, new [] { "A sentence ", "has words." })]
  2285. [InlineData ("A sentence has words.", 8, -13, new [] { "A ", "sentence", " has ", "words." })]
  2286. [InlineData ("A sentence has words.", 6, -15, new [] { "A ", "senten", "ce ", "has ", "words." })]
  2287. [InlineData ("A sentence has words.", 3, -18, new [] { "A ", "sen", "ten", "ce ", "has", " ", "wor", "ds." })]
  2288. [InlineData (
  2289. "A sentence has words.",
  2290. 2,
  2291. -19,
  2292. new [] { "A ", "se", "nt", "en", "ce", " ", "ha", "s ", "wo", "rd", "s." }
  2293. )]
  2294. [InlineData (
  2295. "A sentence has words.",
  2296. 1,
  2297. -20,
  2298. new []
  2299. {
  2300. "A", " ", "s", "e", "n", "t", "e", "n", "c", "e", " ", "h", "a", "s", " ", "w", "o", "r", "d", "s", "."
  2301. }
  2302. )]
  2303. public void WordWrap_PreserveTrailingSpaces_True (
  2304. string text,
  2305. int maxWidth,
  2306. int widthOffset,
  2307. IEnumerable<string> resultLines
  2308. )
  2309. {
  2310. List<string> wrappedLines;
  2311. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  2312. int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
  2313. wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true);
  2314. Assert.Equal (wrappedLines.Count, resultLines.Count ());
  2315. Assert.True (
  2316. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
  2317. );
  2318. Assert.True (
  2319. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
  2320. );
  2321. Assert.Equal (resultLines, wrappedLines);
  2322. }
  2323. [Theory]
  2324. [InlineData ("文に は言葉 があり ます。", 14, 0, new [] { "文に は言葉 ", "があり ます。" })]
  2325. [InlineData ("文に は言葉 があり ます。", 3, -11, new [] { "文", "に ", "は", "言", "葉 ", "が", "あ", "り ", "ま", "す", "。" })]
  2326. [InlineData (
  2327. "文に は言葉 があり ます。",
  2328. 2,
  2329. -12,
  2330. new [] { "文", "に", " ", "は", "言", "葉", " ", "が", "あ", "り", " ", "ま", "す", "。" }
  2331. )]
  2332. [InlineData ("文に は言葉 があり ます。", 1, -13, new string [] { })]
  2333. public void WordWrap_PreserveTrailingSpaces_True_Wide_Runes (
  2334. string text,
  2335. int maxWidth,
  2336. int widthOffset,
  2337. IEnumerable<string> resultLines
  2338. )
  2339. {
  2340. List<string> wrappedLines;
  2341. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  2342. int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
  2343. wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true);
  2344. Assert.Equal (wrappedLines.Count, resultLines.Count ());
  2345. Assert.True (
  2346. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
  2347. );
  2348. Assert.True (
  2349. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
  2350. );
  2351. Assert.Equal (resultLines, wrappedLines);
  2352. }
  2353. [Theory]
  2354. [InlineData ("A sentence has words. ", 3, new [] { "A ", "sen", "ten", "ce ", "has", " ", "wor", "ds.", " " })]
  2355. [InlineData (
  2356. "A sentence has words. ",
  2357. 3,
  2358. new [] { "A ", " ", "sen", "ten", "ce ", " ", " ", " ", "has", " ", "wor", "ds.", " " }
  2359. )]
  2360. public void WordWrap_PreserveTrailingSpaces_True_With_Simple_Runes_Width_3 (
  2361. string text,
  2362. int width,
  2363. IEnumerable<string> resultLines
  2364. )
  2365. {
  2366. List<string> wrappedLines = TextFormatter.WordWrapText (text, width, true);
  2367. Assert.Equal (wrappedLines.Count, resultLines.Count ());
  2368. Assert.Equal (resultLines, wrappedLines);
  2369. var breakLines = "";
  2370. foreach (string line in wrappedLines)
  2371. {
  2372. breakLines += $"{line}{Environment.NewLine}";
  2373. }
  2374. var expected = string.Empty;
  2375. foreach (string line in resultLines)
  2376. {
  2377. expected += $"{line}{Environment.NewLine}";
  2378. }
  2379. Assert.Equal (expected, breakLines);
  2380. // Double space Complex example - this is how VS 2022 does it
  2381. //text = "A sentence has words. ";
  2382. //breakLines = "";
  2383. //wrappedLines = TextFormatter.WordWrapText (text, width, preserveTrailingSpaces: true);
  2384. //foreach (var line in wrappedLines) {
  2385. // breakLines += $"{line}{Environment.NewLine}";
  2386. //}
  2387. //expected = "A " + Environment.NewLine +
  2388. // " se" + Environment.NewLine +
  2389. // " nt" + Environment.NewLine +
  2390. // " en" + Environment.NewLine +
  2391. // " ce" + Environment.NewLine +
  2392. // " " + Environment.NewLine +
  2393. // " " + Environment.NewLine +
  2394. // " " + Environment.NewLine +
  2395. // " ha" + Environment.NewLine +
  2396. // " s " + Environment.NewLine +
  2397. // " wo" + Environment.NewLine +
  2398. // " rd" + Environment.NewLine +
  2399. // " s." + Environment.NewLine;
  2400. //Assert.Equal (expected, breakLines);
  2401. }
  2402. [Theory]
  2403. [InlineData ("A sentence\t\t\t has words.", 14, -10, new [] { "A sentence\t", "\t\t has ", "words." })]
  2404. [InlineData (
  2405. "A sentence\t\t\t has words.",
  2406. 8,
  2407. -16,
  2408. new [] { "A ", "sentence", "\t\t", "\t ", "has ", "words." }
  2409. )]
  2410. [InlineData (
  2411. "A sentence\t\t\t has words.",
  2412. 3,
  2413. -21,
  2414. new [] { "A ", "sen", "ten", "ce", "\t", "\t", "\t", " ", "has", " ", "wor", "ds." }
  2415. )]
  2416. [InlineData (
  2417. "A sentence\t\t\t has words.",
  2418. 2,
  2419. -22,
  2420. new [] { "A ", "se", "nt", "en", "ce", "\t", "\t", "\t", " ", "ha", "s ", "wo", "rd", "s." }
  2421. )]
  2422. [InlineData (
  2423. "A sentence\t\t\t has words.",
  2424. 1,
  2425. -23,
  2426. new []
  2427. {
  2428. "A",
  2429. " ",
  2430. "s",
  2431. "e",
  2432. "n",
  2433. "t",
  2434. "e",
  2435. "n",
  2436. "c",
  2437. "e",
  2438. "\t",
  2439. "\t",
  2440. "\t",
  2441. " ",
  2442. "h",
  2443. "a",
  2444. "s",
  2445. " ",
  2446. "w",
  2447. "o",
  2448. "r",
  2449. "d",
  2450. "s",
  2451. "."
  2452. }
  2453. )]
  2454. public void WordWrap_PreserveTrailingSpaces_True_With_Tab (
  2455. string text,
  2456. int maxWidth,
  2457. int widthOffset,
  2458. IEnumerable<string> resultLines,
  2459. int tabWidth = 4
  2460. )
  2461. {
  2462. List<string> wrappedLines;
  2463. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  2464. int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
  2465. wrappedLines = TextFormatter.WordWrapText (text, maxWidth, true, tabWidth);
  2466. Assert.Equal (wrappedLines.Count, resultLines.Count ());
  2467. Assert.True (
  2468. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
  2469. );
  2470. Assert.True (
  2471. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
  2472. );
  2473. Assert.Equal (resultLines, wrappedLines);
  2474. }
  2475. [Theory]
  2476. [InlineData ("Constantinople", 14, 0, new [] { "Constantinople" })]
  2477. [InlineData ("Constantinople", 12, -2, new [] { "Constantinop", "le" })]
  2478. [InlineData ("Constantinople", 9, -5, new [] { "Constanti", "nople" })]
  2479. [InlineData ("Constantinople", 7, -7, new [] { "Constan", "tinople" })]
  2480. [InlineData ("Constantinople", 5, -9, new [] { "Const", "antin", "ople" })]
  2481. [InlineData ("Constantinople", 4, -10, new [] { "Cons", "tant", "inop", "le" })]
  2482. [InlineData (
  2483. "Constantinople",
  2484. 1,
  2485. -13,
  2486. new [] { "C", "o", "n", "s", "t", "a", "n", "t", "i", "n", "o", "p", "l", "e" }
  2487. )]
  2488. public void WordWrap_SingleWordLine (
  2489. string text,
  2490. int maxWidth,
  2491. int widthOffset,
  2492. IEnumerable<string> resultLines
  2493. )
  2494. {
  2495. List<string> wrappedLines;
  2496. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  2497. int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
  2498. wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
  2499. Assert.Equal (wrappedLines.Count, resultLines.Count ());
  2500. Assert.True (
  2501. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
  2502. );
  2503. Assert.True (
  2504. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
  2505. );
  2506. Assert.Equal (resultLines, wrappedLines);
  2507. }
  2508. [Theory]
  2509. [InlineData ("This\u00A0is\n\u00A0a\u00A0sentence.", 20, 0, new [] { "This\u00A0is\u00A0a\u00A0sentence." })]
  2510. [InlineData ("This\u00A0is\n\u00A0a\u00A0sentence.", 19, -1, new [] { "This\u00A0is\u00A0a\u00A0sentence." })]
  2511. [InlineData (
  2512. "\u00A0\u00A0\u00A0\u00A0\u00A0test\u00A0sentence.",
  2513. 19,
  2514. 0,
  2515. new [] { "\u00A0\u00A0\u00A0\u00A0\u00A0test\u00A0sentence." }
  2516. )]
  2517. public void WordWrap_Unicode_2LinesWithNonBreakingSpace (
  2518. string text,
  2519. int maxWidth,
  2520. int widthOffset,
  2521. IEnumerable<string> resultLines
  2522. )
  2523. {
  2524. List<string> wrappedLines;
  2525. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  2526. int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
  2527. wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
  2528. Assert.Equal (wrappedLines.Count, resultLines.Count ());
  2529. Assert.True (
  2530. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
  2531. );
  2532. Assert.True (
  2533. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
  2534. );
  2535. Assert.Equal (resultLines, wrappedLines);
  2536. }
  2537. [Theory]
  2538. [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 19, 0, new [] { "This\u00A0is\u00A0a\u00A0sentence." })]
  2539. [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 18, -1, new [] { "This\u00A0is\u00A0a\u00A0sentence", "." })]
  2540. [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 17, -2, new [] { "This\u00A0is\u00A0a\u00A0sentenc", "e." })]
  2541. [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 14, -5, new [] { "This\u00A0is\u00A0a\u00A0sent", "ence." })]
  2542. [InlineData ("This\u00A0is\u00A0a\u00A0sentence.", 10, -9, new [] { "This\u00A0is\u00A0a\u00A0", "sentence." })]
  2543. [InlineData (
  2544. "This\u00A0is\u00A0a\u00A0sentence.",
  2545. 7,
  2546. -12,
  2547. new [] { "This\u00A0is", "\u00A0a\u00A0sent", "ence." }
  2548. )]
  2549. [InlineData (
  2550. "This\u00A0is\u00A0a\u00A0sentence.",
  2551. 5,
  2552. -14,
  2553. new [] { "This\u00A0", "is\u00A0a\u00A0", "sente", "nce." }
  2554. )]
  2555. [InlineData (
  2556. "This\u00A0is\u00A0a\u00A0sentence.",
  2557. 1,
  2558. -18,
  2559. new []
  2560. {
  2561. "T", "h", "i", "s", "\u00A0", "i", "s", "\u00A0", "a", "\u00A0", "s", "e", "n", "t", "e", "n", "c", "e", "."
  2562. }
  2563. )]
  2564. public void WordWrap_Unicode_LineWithNonBreakingSpace (
  2565. string text,
  2566. int maxWidth,
  2567. int widthOffset,
  2568. IEnumerable<string> resultLines
  2569. )
  2570. {
  2571. List<string> wrappedLines;
  2572. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  2573. int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
  2574. wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
  2575. Assert.Equal (wrappedLines.Count, resultLines.Count ());
  2576. Assert.True (
  2577. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
  2578. );
  2579. Assert.True (
  2580. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
  2581. );
  2582. Assert.Equal (resultLines, wrappedLines);
  2583. }
  2584. [Theory]
  2585. [InlineData (
  2586. "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
  2587. 51,
  2588. 0,
  2589. new [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ" }
  2590. )]
  2591. [InlineData (
  2592. "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
  2593. 50,
  2594. -1,
  2595. new [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ" }
  2596. )]
  2597. [InlineData (
  2598. "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
  2599. 46,
  2600. -5,
  2601. new [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮ", "ฯะัาำ" }
  2602. )]
  2603. [InlineData (
  2604. "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
  2605. 26,
  2606. -25,
  2607. new [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบ", "ปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ" }
  2608. )]
  2609. [InlineData (
  2610. "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
  2611. 17,
  2612. -34,
  2613. new [] { "กขฃคฅฆงจฉชซฌญฎฏฐฑ", "ฒณดตถทธนบปผฝพฟภมย", "รฤลฦวศษสหฬอฮฯะัาำ" }
  2614. )]
  2615. [InlineData (
  2616. "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
  2617. 13,
  2618. -38,
  2619. new [] { "กขฃคฅฆงจฉชซฌญ", "ฎฏฐฑฒณดตถทธนบ", "ปผฝพฟภมยรฤลฦว", "ศษสหฬอฮฯะัาำ" }
  2620. )]
  2621. [InlineData (
  2622. "กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำ",
  2623. 1,
  2624. -50,
  2625. new []
  2626. {
  2627. "ก",
  2628. "ข",
  2629. "ฃ",
  2630. "ค",
  2631. "ฅ",
  2632. "ฆ",
  2633. "ง",
  2634. "จ",
  2635. "ฉ",
  2636. "ช",
  2637. "ซ",
  2638. "ฌ",
  2639. "ญ",
  2640. "ฎ",
  2641. "ฏ",
  2642. "ฐ",
  2643. "ฑ",
  2644. "ฒ",
  2645. "ณ",
  2646. "ด",
  2647. "ต",
  2648. "ถ",
  2649. "ท",
  2650. "ธ",
  2651. "น",
  2652. "บ",
  2653. "ป",
  2654. "ผ",
  2655. "ฝ",
  2656. "พ",
  2657. "ฟ",
  2658. "ภ",
  2659. "ม",
  2660. "ย",
  2661. "ร",
  2662. "ฤ",
  2663. "ล",
  2664. "ฦ",
  2665. "ว",
  2666. "ศ",
  2667. "ษ",
  2668. "ส",
  2669. "ห",
  2670. "ฬ",
  2671. "อ",
  2672. "ฮ",
  2673. "ฯ",
  2674. "ะั",
  2675. "า",
  2676. "ำ"
  2677. }
  2678. )]
  2679. public void WordWrap_Unicode_SingleWordLine (
  2680. string text,
  2681. int maxWidth,
  2682. int widthOffset,
  2683. IEnumerable<string> resultLines
  2684. )
  2685. {
  2686. List<string> wrappedLines;
  2687. IEnumerable<Rune> zeroWidth = text.EnumerateRunes ().Where (r => r.GetColumns () == 0);
  2688. Assert.Single (zeroWidth);
  2689. Assert.Equal ('ั', zeroWidth.ElementAt (0).Value);
  2690. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  2691. int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
  2692. wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
  2693. Assert.Equal (wrappedLines.Count, resultLines.Count ());
  2694. Assert.True (
  2695. expectedClippedWidth
  2696. >= (wrappedLines.Count > 0
  2697. ? wrappedLines.Max (
  2698. l => l.GetRuneCount ()
  2699. + zeroWidth.Count ()
  2700. - 1
  2701. + widthOffset
  2702. )
  2703. : 0)
  2704. );
  2705. Assert.True (
  2706. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
  2707. );
  2708. Assert.Equal (resultLines, wrappedLines);
  2709. }
  2710. /// <summary>WordWrap strips CRLF</summary>
  2711. [Theory]
  2712. [InlineData (
  2713. "A sentence has words.\nA paragraph has lines.",
  2714. 44,
  2715. 0,
  2716. new [] { "A sentence has words.A paragraph has lines." }
  2717. )]
  2718. [InlineData (
  2719. "A sentence has words.\nA paragraph has lines.",
  2720. 43,
  2721. -1,
  2722. new [] { "A sentence has words.A paragraph has lines." }
  2723. )]
  2724. [InlineData (
  2725. "A sentence has words.\nA paragraph has lines.",
  2726. 38,
  2727. -6,
  2728. new [] { "A sentence has words.A paragraph has", "lines." }
  2729. )]
  2730. [InlineData (
  2731. "A sentence has words.\nA paragraph has lines.",
  2732. 34,
  2733. -10,
  2734. new [] { "A sentence has words.A paragraph", "has lines." }
  2735. )]
  2736. [InlineData (
  2737. "A sentence has words.\nA paragraph has lines.",
  2738. 27,
  2739. -17,
  2740. new [] { "A sentence has words.A", "paragraph has lines." }
  2741. )]
  2742. // Unicode
  2743. [InlineData (
  2744. "A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.",
  2745. 69,
  2746. 0,
  2747. new [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт has Линии." }
  2748. )]
  2749. [InlineData (
  2750. "A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.",
  2751. 68,
  2752. -1,
  2753. new [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт has Линии." }
  2754. )]
  2755. [InlineData (
  2756. "A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.",
  2757. 63,
  2758. -6,
  2759. new [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт has", "Линии." }
  2760. )]
  2761. [InlineData (
  2762. "A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.",
  2763. 59,
  2764. -10,
  2765. new [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode Пункт", "has Линии." }
  2766. )]
  2767. [InlineData (
  2768. "A Unicode sentence (пÑивеÑ) has words.\nA Unicode Пункт has Линии.",
  2769. 52,
  2770. -17,
  2771. new [] { "A Unicode sentence (пÑивеÑ) has words.A Unicode", "Пункт has Линии." }
  2772. )]
  2773. public void WordWrap_WithNewLines (string text, int maxWidth, int widthOffset, IEnumerable<string> resultLines)
  2774. {
  2775. List<string> wrappedLines;
  2776. Assert.Equal (maxWidth, text.GetRuneCount () + widthOffset);
  2777. int expectedClippedWidth = Math.Min (text.GetRuneCount (), maxWidth);
  2778. wrappedLines = TextFormatter.WordWrapText (text, maxWidth);
  2779. Assert.Equal (wrappedLines.Count, resultLines.Count ());
  2780. Assert.True (
  2781. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetRuneCount ()) : 0)
  2782. );
  2783. Assert.True (
  2784. expectedClippedWidth >= (wrappedLines.Count > 0 ? wrappedLines.Max (l => l.GetColumns ()) : 0)
  2785. );
  2786. Assert.Equal (resultLines, wrappedLines);
  2787. }
  2788. [SetupFakeDriver]
  2789. [Theory]
  2790. [InlineData ("A", 0, "")]
  2791. [InlineData ("A", 1, "A")]
  2792. [InlineData ("A", 2, "A")]
  2793. [InlineData ("AB", 1, "A")]
  2794. [InlineData ("AB", 2, "AB")]
  2795. [InlineData ("ABC", 3, "ABC")]
  2796. [InlineData ("ABC", 4, "ABC")]
  2797. [InlineData ("ABC", 6, "ABC")]
  2798. public void Draw_Horizontal_Left (string text, int width, string expectedText)
  2799. {
  2800. TextFormatter tf = new ()
  2801. {
  2802. Text = text,
  2803. Alignment = Alignment.Start
  2804. };
  2805. tf.ConstrainToWidth = width;
  2806. tf.ConstrainToHeight = 1;
  2807. tf.Draw (new (0, 0, width, 1), Attribute.Default, Attribute.Default);
  2808. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  2809. }
  2810. [SetupFakeDriver]
  2811. [Theory]
  2812. [InlineData ("A", 0, "")]
  2813. [InlineData ("A", 1, "A")]
  2814. [InlineData ("A", 2, " A")]
  2815. [InlineData ("AB", 1, "B")]
  2816. [InlineData ("AB", 2, "AB")]
  2817. [InlineData ("ABC", 3, "ABC")]
  2818. [InlineData ("ABC", 4, " ABC")]
  2819. [InlineData ("ABC", 6, " ABC")]
  2820. public void Draw_Horizontal_Right (string text, int width, string expectedText)
  2821. {
  2822. TextFormatter tf = new ()
  2823. {
  2824. Text = text,
  2825. Alignment = Alignment.End
  2826. };
  2827. tf.ConstrainToWidth = width;
  2828. tf.ConstrainToHeight = 1;
  2829. tf.Draw (new (Point.Empty, new (width, 1)), Attribute.Default, Attribute.Default);
  2830. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  2831. }
  2832. [SetupFakeDriver]
  2833. [Theory]
  2834. [InlineData ("A", 0, "")]
  2835. [InlineData ("A", 1, "A")]
  2836. [InlineData ("A", 2, "A")]
  2837. [InlineData ("A", 3, " A")]
  2838. [InlineData ("AB", 1, "A")]
  2839. [InlineData ("AB", 2, "AB")]
  2840. [InlineData ("ABC", 3, "ABC")]
  2841. [InlineData ("ABC", 4, "ABC")]
  2842. [InlineData ("ABC", 5, " ABC")]
  2843. [InlineData ("ABC", 6, " ABC")]
  2844. [InlineData ("ABC", 9, " ABC")]
  2845. public void Draw_Horizontal_Centered (string text, int width, string expectedText)
  2846. {
  2847. TextFormatter tf = new ()
  2848. {
  2849. Text = text,
  2850. Alignment = Alignment.Center
  2851. };
  2852. tf.ConstrainToWidth = width;
  2853. tf.ConstrainToHeight = 1;
  2854. tf.Draw (new (0, 0, width, 1), Attribute.Default, Attribute.Default);
  2855. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  2856. }
  2857. [SetupFakeDriver]
  2858. [Theory]
  2859. [InlineData ("A", 0, "")]
  2860. [InlineData ("A", 1, "A")]
  2861. [InlineData ("A", 2, "A")]
  2862. [InlineData ("A B", 3, "A B")]
  2863. [InlineData ("A B", 1, "A")]
  2864. [InlineData ("A B", 2, "A")]
  2865. [InlineData ("A B", 4, "A B")]
  2866. [InlineData ("A B", 5, "A B")]
  2867. [InlineData ("A B", 6, "A B")]
  2868. [InlineData ("A B", 10, "A B")]
  2869. [InlineData ("ABC ABC", 10, "ABC ABC")]
  2870. public void Draw_Horizontal_Justified (string text, int width, string expectedText)
  2871. {
  2872. TextFormatter tf = new ()
  2873. {
  2874. Text = text,
  2875. Alignment = Alignment.Fill
  2876. };
  2877. tf.ConstrainToWidth = width;
  2878. tf.ConstrainToHeight = 1;
  2879. tf.Draw (new (0, 0, width, 1), Attribute.Default, Attribute.Default);
  2880. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  2881. }
  2882. [SetupFakeDriver]
  2883. [Theory]
  2884. [InlineData ("A", 5, 5, "A")]
  2885. [InlineData (
  2886. "AB12",
  2887. 5,
  2888. 5,
  2889. @"
  2890. A
  2891. B
  2892. 1
  2893. 2")]
  2894. [InlineData (
  2895. "AB\n12",
  2896. 5,
  2897. 5,
  2898. @"
  2899. A1
  2900. B2")]
  2901. [InlineData ("", 5, 1, "")]
  2902. [InlineData (
  2903. "Hello Worlds",
  2904. 1,
  2905. 12,
  2906. @"
  2907. H
  2908. e
  2909. l
  2910. l
  2911. o
  2912. W
  2913. o
  2914. r
  2915. l
  2916. d
  2917. s")]
  2918. [InlineData (
  2919. "Hello Worlds",
  2920. 1,
  2921. 12,
  2922. @"
  2923. H
  2924. e
  2925. l
  2926. l
  2927. o
  2928. W
  2929. o
  2930. r
  2931. l
  2932. d
  2933. s")]
  2934. [InlineData ("Hello Worlds", 12, 1, @"HelloWorlds")]
  2935. public void Draw_Vertical_TopBottom_LeftRight (string text, int width, int height, string expectedText)
  2936. {
  2937. TextFormatter tf = new ()
  2938. {
  2939. Text = text,
  2940. Direction = TextDirection.TopBottom_LeftRight
  2941. };
  2942. tf.ConstrainToWidth = width;
  2943. tf.ConstrainToHeight = height;
  2944. tf.Draw (new (0, 0, 20, 20), Attribute.Default, Attribute.Default);
  2945. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  2946. }
  2947. [SetupFakeDriver]
  2948. [Theory]
  2949. [InlineData ("Hello World", 15, 1, "Hello World")]
  2950. [InlineData (
  2951. "Well Done\nNice Work",
  2952. 15,
  2953. 2,
  2954. @"
  2955. Well Done
  2956. Nice Work")]
  2957. [InlineData ("你好 世界", 15, 1, "你好 世界")]
  2958. [InlineData (
  2959. "做 得好\n幹 得好",
  2960. 15,
  2961. 2,
  2962. @"
  2963. 做 得好
  2964. 幹 得好")]
  2965. public void Justify_Horizontal (string text, int width, int height, string expectedText)
  2966. {
  2967. TextFormatter tf = new ()
  2968. {
  2969. Text = text,
  2970. Alignment = Alignment.Fill,
  2971. ConstrainToSize = new Size (width, height),
  2972. MultiLine = true
  2973. };
  2974. tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default);
  2975. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  2976. }
  2977. [SetupFakeDriver]
  2978. [Theory]
  2979. [InlineData ("Hello World", 1, 15, "H\ne\nl\nl\no\n \n \n \n \n \nW\no\nr\nl\nd")]
  2980. [InlineData (
  2981. "Well Done\nNice Work",
  2982. 2,
  2983. 15,
  2984. @"
  2985. WN
  2986. ei
  2987. lc
  2988. le
  2989. DW
  2990. oo
  2991. nr
  2992. ek")]
  2993. [InlineData ("你好 世界", 2, 15, "你\n好\n \n \n \n \n \n \n \n \n \n \n \n世\n界")]
  2994. [InlineData (
  2995. "做 得好\n幹 得好",
  2996. 4,
  2997. 15,
  2998. @"
  2999. 做幹
  3000. 得得
  3001. 好好")]
  3002. public void Justify_Vertical (string text, int width, int height, string expectedText)
  3003. {
  3004. TextFormatter tf = new ()
  3005. {
  3006. Text = text,
  3007. Direction = TextDirection.TopBottom_LeftRight,
  3008. VerticalAlignment = Alignment.Fill,
  3009. ConstrainToSize = new Size (width, height),
  3010. MultiLine = true
  3011. };
  3012. tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default);
  3013. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  3014. }
  3015. [SetupFakeDriver]
  3016. [Theory]
  3017. [InlineData ("A", 0, 1, "", 0)]
  3018. [InlineData ("A", 1, 1, "A", 0)]
  3019. [InlineData ("A", 2, 2, " A", 1)]
  3020. [InlineData ("AB", 1, 1, "B", 0)]
  3021. [InlineData ("AB", 2, 2, " A\n B", 0)]
  3022. [InlineData ("ABC", 3, 2, " B\n C", 0)]
  3023. [InlineData ("ABC", 4, 2, " B\n C", 0)]
  3024. [InlineData ("ABC", 6, 2, " B\n C", 0)]
  3025. [InlineData ("こんにちは", 0, 1, "", 0)]
  3026. [InlineData ("こんにちは", 1, 0, "", 0)]
  3027. [InlineData ("こんにちは", 1, 1, "", 0)]
  3028. [InlineData ("こんにちは", 2, 1, "は", 0)]
  3029. [InlineData ("こんにちは", 2, 2, "ち\nは", 0)]
  3030. [InlineData ("こんにちは", 2, 3, "に\nち\nは", 0)]
  3031. [InlineData ("こんにちは", 2, 4, "ん\nに\nち\nは", 0)]
  3032. [InlineData ("こんにちは", 2, 5, "こ\nん\nに\nち\nは", 0)]
  3033. [InlineData ("こんにちは", 2, 6, "こ\nん\nに\nち\nは", 1)]
  3034. [InlineData ("ABCD\nこんにちは", 4, 7, " こ\n Aん\n Bに\n Cち\n Dは", 2)]
  3035. [InlineData ("こんにちは\nABCD", 3, 7, "こ \nんA\nにB\nちC\nはD", 2)]
  3036. public void Draw_Vertical_Bottom_Horizontal_Right (string text, int width, int height, string expectedText, int expectedY)
  3037. {
  3038. TextFormatter tf = new ()
  3039. {
  3040. Text = text,
  3041. Alignment = Alignment.End,
  3042. Direction = TextDirection.TopBottom_LeftRight,
  3043. VerticalAlignment = Alignment.End
  3044. };
  3045. tf.ConstrainToWidth = width;
  3046. tf.ConstrainToHeight = height;
  3047. tf.Draw (new (Point.Empty, new (width, height)), Attribute.Default, Attribute.Default);
  3048. Rectangle rect = TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  3049. Assert.Equal (expectedY, rect.Y);
  3050. }
  3051. [SetupFakeDriver]
  3052. [Theory]
  3053. [InlineData ("A", 5, "A")]
  3054. [InlineData (
  3055. "AB12",
  3056. 5,
  3057. @"
  3058. A
  3059. B
  3060. 1
  3061. 2")]
  3062. [InlineData (
  3063. "AB\n12",
  3064. 5,
  3065. @"
  3066. A1
  3067. B2")]
  3068. [InlineData ("", 1, "")]
  3069. [InlineData (
  3070. "AB1 2",
  3071. 2,
  3072. @"
  3073. A12
  3074. B ")]
  3075. [InlineData (
  3076. "こんにちは",
  3077. 1,
  3078. @"
  3079. こん")]
  3080. [InlineData (
  3081. "こんにちは",
  3082. 2,
  3083. @"
  3084. こに
  3085. んち")]
  3086. [InlineData (
  3087. "こんにちは",
  3088. 5,
  3089. @"
  3090. は")]
  3091. public void Draw_Vertical_TopBottom_LeftRight_Top (string text, int height, string expectedText)
  3092. {
  3093. TextFormatter tf = new ()
  3094. {
  3095. Text = text,
  3096. Direction = TextDirection.TopBottom_LeftRight
  3097. };
  3098. tf.ConstrainToWidth = 5;
  3099. tf.ConstrainToHeight = height;
  3100. tf.Draw (new (0, 0, 5, height), Attribute.Default, Attribute.Default);
  3101. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  3102. }
  3103. [SetupFakeDriver]
  3104. [Theory]
  3105. // The expectedY param is to probe that the expectedText param start at that Y coordinate
  3106. [InlineData ("A", 0, "", 0)]
  3107. [InlineData ("A", 1, "A", 0)]
  3108. [InlineData ("A", 2, "A", 0)]
  3109. [InlineData ("A", 3, "A", 1)]
  3110. [InlineData ("AB", 1, "A", 0)]
  3111. [InlineData ("AB", 2, "A\nB", 0)]
  3112. [InlineData ("ABC", 2, "A\nB", 0)]
  3113. [InlineData ("ABC", 3, "A\nB\nC", 0)]
  3114. [InlineData ("ABC", 4, "A\nB\nC", 0)]
  3115. [InlineData ("ABC", 5, "A\nB\nC", 1)]
  3116. [InlineData ("ABC", 6, "A\nB\nC", 1)]
  3117. [InlineData ("ABC", 9, "A\nB\nC", 3)]
  3118. [InlineData ("ABCD", 2, "B\nC", 0)]
  3119. [InlineData ("こんにちは", 0, "", 0)]
  3120. [InlineData ("こんにちは", 1, "に", 0)]
  3121. [InlineData ("こんにちは", 2, "ん\nに", 0)]
  3122. [InlineData ("こんにちは", 3, "ん\nに\nち", 0)]
  3123. [InlineData ("こんにちは", 4, "こ\nん\nに\nち", 0)]
  3124. [InlineData ("こんにちは", 5, "こ\nん\nに\nち\nは", 0)]
  3125. [InlineData ("こんにちは", 6, "こ\nん\nに\nち\nは", 0)]
  3126. [InlineData ("ABCD\nこんにちは", 7, "Aこ\nBん\nCに\nDち\n は", 1)]
  3127. [InlineData ("こんにちは\nABCD", 7, "こA\nんB\nにC\nちD\nは ", 1)]
  3128. public void Draw_Vertical_TopBottom_LeftRight_Middle (string text, int height, string expectedText, int expectedY)
  3129. {
  3130. TextFormatter tf = new ()
  3131. {
  3132. Text = text,
  3133. Direction = TextDirection.TopBottom_LeftRight,
  3134. VerticalAlignment = Alignment.Center
  3135. };
  3136. int width = text.ToRunes ().Max (r => r.GetColumns ());
  3137. if (text.Contains ("\n"))
  3138. {
  3139. width++;
  3140. }
  3141. tf.ConstrainToWidth = width;
  3142. tf.ConstrainToHeight = height;
  3143. tf.Draw (new (0, 0, 5, height), Attribute.Default, Attribute.Default);
  3144. Rectangle rect = TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  3145. Assert.Equal (expectedY, rect.Y);
  3146. }
  3147. [SetupFakeDriver]
  3148. [Theory]
  3149. [InlineData ("A", 1, 0, "")]
  3150. [InlineData ("A", 0, 1, "")]
  3151. [InlineData ("AB1 2", 2, 1, "2")]
  3152. [InlineData ("AB12", 5, 1, "21BA")]
  3153. [InlineData ("AB\n12", 5, 2, "BA\n21")]
  3154. [InlineData ("ABC 123 456", 7, 2, "654 321\nCBA ")]
  3155. [InlineData ("こんにちは", 1, 1, "")]
  3156. [InlineData ("こんにちは", 2, 1, "は")]
  3157. [InlineData ("こんにちは", 5, 1, "はち")]
  3158. [InlineData ("こんにちは", 10, 1, "はちにんこ")]
  3159. [InlineData ("こんにちは\nAB\n12", 10, 3, "はちにんこ\nBA \n21 ")]
  3160. public void Draw_Horizontal_RightLeft_TopBottom (string text, int width, int height, string expectedText)
  3161. {
  3162. TextFormatter tf = new ()
  3163. {
  3164. Text = text,
  3165. Direction = TextDirection.RightLeft_TopBottom
  3166. };
  3167. tf.ConstrainToWidth = width;
  3168. tf.ConstrainToHeight = height;
  3169. tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default);
  3170. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  3171. }
  3172. [SetupFakeDriver]
  3173. [Theory]
  3174. [InlineData ("A", 1, 0, "")]
  3175. [InlineData ("A", 0, 1, "")]
  3176. [InlineData ("AB1 2", 2, 1, "2")]
  3177. [InlineData ("AB12", 5, 1, "21BA")]
  3178. [InlineData ("AB\n12", 5, 2, "21\nBA")]
  3179. [InlineData ("ABC 123 456", 7, 2, "CBA \n654 321")]
  3180. [InlineData ("こんにちは", 1, 1, "")]
  3181. [InlineData ("こんにちは", 2, 1, "は")]
  3182. [InlineData ("こんにちは", 5, 1, "はち")]
  3183. [InlineData ("こんにちは", 10, 1, "はちにんこ")]
  3184. [InlineData ("こんにちは\nAB\n12", 10, 3, "21 \nBA \nはちにんこ")]
  3185. public void Draw_Horizontal_RightLeft_BottomTop (string text, int width, int height, string expectedText)
  3186. {
  3187. TextFormatter tf = new ()
  3188. {
  3189. Text = text,
  3190. Direction = TextDirection.RightLeft_BottomTop
  3191. };
  3192. tf.ConstrainToWidth = width;
  3193. tf.ConstrainToHeight = height;
  3194. tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default);
  3195. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  3196. }
  3197. [SetupFakeDriver]
  3198. [Theory]
  3199. [InlineData ("A", 1, 0, "")]
  3200. [InlineData ("A", 0, 1, "")]
  3201. [InlineData ("AB1 2", 1, 2, "2")]
  3202. [InlineData ("AB12", 1, 5, "2\n1\nB\nA")]
  3203. [InlineData ("AB\n12", 2, 5, "B2\nA1")]
  3204. [InlineData ("ABC 123 456", 2, 7, "6C\n5B\n4A\n \n3 \n2 \n1 ")]
  3205. [InlineData ("こんにちは", 1, 1, "")]
  3206. [InlineData ("こんにちは", 2, 1, "は")]
  3207. [InlineData ("こんにちは", 2, 5, "は\nち\nに\nん\nこ")]
  3208. [InlineData ("こんにちは", 2, 10, "は\nち\nに\nん\nこ")]
  3209. [InlineData ("こんにちは\nAB\n12", 4, 10, "はB2\nちA1\nに \nん \nこ ")]
  3210. public void Draw_Vertical_BottomTop_LeftRight (string text, int width, int height, string expectedText)
  3211. {
  3212. TextFormatter tf = new ()
  3213. {
  3214. Text = text,
  3215. Direction = TextDirection.BottomTop_LeftRight
  3216. };
  3217. tf.ConstrainToWidth = width;
  3218. tf.ConstrainToHeight = height;
  3219. tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default);
  3220. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  3221. }
  3222. [SetupFakeDriver]
  3223. [Theory]
  3224. [InlineData ("A", 1, 0, "")]
  3225. [InlineData ("A", 0, 1, "")]
  3226. [InlineData ("AB1 2", 1, 2, "2")]
  3227. [InlineData ("AB12", 1, 5, "2\n1\nB\nA")]
  3228. [InlineData ("AB\n12", 2, 5, "2B\n1A")]
  3229. [InlineData ("ABC 123 456", 2, 7, "C6\nB5\nA4\n \n 3\n 2\n 1")]
  3230. [InlineData ("こんにちは", 1, 1, "")]
  3231. [InlineData ("こんにちは", 2, 1, "は")]
  3232. [InlineData ("こんにちは", 2, 5, "は\nち\nに\nん\nこ")]
  3233. [InlineData ("こんにちは", 2, 10, "は\nち\nに\nん\nこ")]
  3234. [InlineData ("こんにちは\nAB\n12", 4, 10, "2Bは\n1Aち\n に\n ん\n こ")]
  3235. public void Draw_Vertical_BottomTop_RightLeft (string text, int width, int height, string expectedText)
  3236. {
  3237. TextFormatter tf = new ()
  3238. {
  3239. Text = text,
  3240. Direction = TextDirection.BottomTop_RightLeft
  3241. };
  3242. tf.ConstrainToWidth = width;
  3243. tf.ConstrainToHeight = height;
  3244. tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default);
  3245. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  3246. }
  3247. // Draw tests - Note that these depend on View
  3248. [Fact]
  3249. [TestRespondersDisposed]
  3250. public void Draw_Vertical_Throws_IndexOutOfRangeException_With_Negative_Bounds ()
  3251. {
  3252. Application.Init (new FakeDriver ());
  3253. Toplevel top = new ();
  3254. var view = new View { Y = -2, Height = 10, TextDirection = TextDirection.TopBottom_LeftRight, Text = "view" };
  3255. top.Add (view);
  3256. Application.Iteration += (s, a) =>
  3257. {
  3258. Assert.Equal (-2, view.Y);
  3259. Application.RequestStop ();
  3260. };
  3261. try
  3262. {
  3263. Application.Run (top);
  3264. }
  3265. catch (IndexOutOfRangeException ex)
  3266. {
  3267. // After the fix this exception will not be caught.
  3268. Assert.IsType<IndexOutOfRangeException> (ex);
  3269. }
  3270. top.Dispose ();
  3271. // Shutdown must be called to safely clean up Application if Init has been called
  3272. Application.Shutdown ();
  3273. }
  3274. [SetupFakeDriver]
  3275. [Theory]
  3276. // Horizontal with Alignment.Start
  3277. // LeftRight_TopBottom
  3278. [InlineData (
  3279. "0 2 4",
  3280. Alignment.Start,
  3281. Alignment.Start,
  3282. TextDirection.LeftRight_TopBottom,
  3283. @"
  3284. 0 2 4**
  3285. *******
  3286. *******
  3287. *******
  3288. *******
  3289. *******
  3290. *******")]
  3291. [InlineData (
  3292. "0 2 4",
  3293. Alignment.End,
  3294. Alignment.Start,
  3295. TextDirection.LeftRight_TopBottom,
  3296. @"
  3297. **0 2 4
  3298. *******
  3299. *******
  3300. *******
  3301. *******
  3302. *******
  3303. *******")]
  3304. [InlineData (
  3305. "0 2 4",
  3306. Alignment.Center,
  3307. Alignment.Start,
  3308. TextDirection.LeftRight_TopBottom,
  3309. @"
  3310. *0 2 4*
  3311. *******
  3312. *******
  3313. *******
  3314. *******
  3315. *******
  3316. *******")]
  3317. [InlineData (
  3318. "0 2 4",
  3319. Alignment.Fill,
  3320. Alignment.Start,
  3321. TextDirection.LeftRight_TopBottom,
  3322. @"
  3323. 0 2 4
  3324. *******
  3325. *******
  3326. *******
  3327. *******
  3328. *******
  3329. *******")]
  3330. [InlineData (
  3331. "0 你 4",
  3332. Alignment.Start,
  3333. Alignment.Start,
  3334. TextDirection.LeftRight_TopBottom,
  3335. @"
  3336. 0 你 4*
  3337. *******
  3338. *******
  3339. *******
  3340. *******
  3341. *******
  3342. *******")]
  3343. [InlineData (
  3344. "0 你 4",
  3345. Alignment.End,
  3346. Alignment.Start,
  3347. TextDirection.LeftRight_TopBottom,
  3348. @"
  3349. *0 你 4
  3350. *******
  3351. *******
  3352. *******
  3353. *******
  3354. *******
  3355. *******")]
  3356. [InlineData (
  3357. "0 你 4",
  3358. Alignment.Center,
  3359. Alignment.Start,
  3360. TextDirection.LeftRight_TopBottom,
  3361. @"
  3362. 0 你 4*
  3363. *******
  3364. *******
  3365. *******
  3366. *******
  3367. *******
  3368. *******")]
  3369. [InlineData (
  3370. "0 你 4",
  3371. Alignment.Fill,
  3372. Alignment.Start,
  3373. TextDirection.LeftRight_TopBottom,
  3374. @"
  3375. 0 你 4
  3376. *******
  3377. *******
  3378. *******
  3379. *******
  3380. *******
  3381. *******")]
  3382. // LeftRight_BottomTop
  3383. [InlineData (
  3384. "0 2 4",
  3385. Alignment.Start,
  3386. Alignment.Start,
  3387. TextDirection.LeftRight_BottomTop,
  3388. @"
  3389. 0 2 4**
  3390. *******
  3391. *******
  3392. *******
  3393. *******
  3394. *******
  3395. *******")]
  3396. [InlineData (
  3397. "0 2 4",
  3398. Alignment.End,
  3399. Alignment.Start,
  3400. TextDirection.LeftRight_BottomTop,
  3401. @"
  3402. **0 2 4
  3403. *******
  3404. *******
  3405. *******
  3406. *******
  3407. *******
  3408. *******")]
  3409. [InlineData (
  3410. "0 2 4",
  3411. Alignment.Center,
  3412. Alignment.Start,
  3413. TextDirection.LeftRight_BottomTop,
  3414. @"
  3415. *0 2 4*
  3416. *******
  3417. *******
  3418. *******
  3419. *******
  3420. *******
  3421. *******")]
  3422. [InlineData (
  3423. "0 2 4",
  3424. Alignment.Fill,
  3425. Alignment.Start,
  3426. TextDirection.LeftRight_BottomTop,
  3427. @"
  3428. 0 2 4
  3429. *******
  3430. *******
  3431. *******
  3432. *******
  3433. *******
  3434. *******")]
  3435. [InlineData (
  3436. "0 你 4",
  3437. Alignment.Start,
  3438. Alignment.Start,
  3439. TextDirection.LeftRight_BottomTop,
  3440. @"
  3441. 0 你 4*
  3442. *******
  3443. *******
  3444. *******
  3445. *******
  3446. *******
  3447. *******")]
  3448. [InlineData (
  3449. "0 你 4",
  3450. Alignment.End,
  3451. Alignment.Start,
  3452. TextDirection.LeftRight_BottomTop,
  3453. @"
  3454. *0 你 4
  3455. *******
  3456. *******
  3457. *******
  3458. *******
  3459. *******
  3460. *******")]
  3461. [InlineData (
  3462. "0 你 4",
  3463. Alignment.Center,
  3464. Alignment.Start,
  3465. TextDirection.LeftRight_BottomTop,
  3466. @"
  3467. 0 你 4*
  3468. *******
  3469. *******
  3470. *******
  3471. *******
  3472. *******
  3473. *******")]
  3474. [InlineData (
  3475. "0 你 4",
  3476. Alignment.Fill,
  3477. Alignment.Start,
  3478. TextDirection.LeftRight_BottomTop,
  3479. @"
  3480. 0 你 4
  3481. *******
  3482. *******
  3483. *******
  3484. *******
  3485. *******
  3486. *******")]
  3487. // RightLeft_TopBottom
  3488. [InlineData (
  3489. "0 2 4",
  3490. Alignment.Start,
  3491. Alignment.Start,
  3492. TextDirection.RightLeft_TopBottom,
  3493. @"
  3494. 4 2 0**
  3495. *******
  3496. *******
  3497. *******
  3498. *******
  3499. *******
  3500. *******")]
  3501. [InlineData (
  3502. "0 2 4",
  3503. Alignment.End,
  3504. Alignment.Start,
  3505. TextDirection.RightLeft_TopBottom,
  3506. @"
  3507. **4 2 0
  3508. *******
  3509. *******
  3510. *******
  3511. *******
  3512. *******
  3513. *******")]
  3514. [InlineData (
  3515. "0 2 4",
  3516. Alignment.Center,
  3517. Alignment.Start,
  3518. TextDirection.RightLeft_TopBottom,
  3519. @"
  3520. *4 2 0*
  3521. *******
  3522. *******
  3523. *******
  3524. *******
  3525. *******
  3526. *******")]
  3527. [InlineData (
  3528. "0 2 4",
  3529. Alignment.Fill,
  3530. Alignment.Start,
  3531. TextDirection.RightLeft_TopBottom,
  3532. @"
  3533. 4 2 0
  3534. *******
  3535. *******
  3536. *******
  3537. *******
  3538. *******
  3539. *******")]
  3540. [InlineData (
  3541. "0 你 4",
  3542. Alignment.Start,
  3543. Alignment.Start,
  3544. TextDirection.RightLeft_TopBottom,
  3545. @"
  3546. 4 你 0*
  3547. *******
  3548. *******
  3549. *******
  3550. *******
  3551. *******
  3552. *******")]
  3553. [InlineData (
  3554. "0 你 4",
  3555. Alignment.End,
  3556. Alignment.Start,
  3557. TextDirection.RightLeft_TopBottom,
  3558. @"
  3559. *4 你 0
  3560. *******
  3561. *******
  3562. *******
  3563. *******
  3564. *******
  3565. *******")]
  3566. [InlineData (
  3567. "0 你 4",
  3568. Alignment.Center,
  3569. Alignment.Start,
  3570. TextDirection.RightLeft_TopBottom,
  3571. @"
  3572. 4 你 0*
  3573. *******
  3574. *******
  3575. *******
  3576. *******
  3577. *******
  3578. *******")]
  3579. [InlineData (
  3580. "0 你 4",
  3581. Alignment.Fill,
  3582. Alignment.Start,
  3583. TextDirection.RightLeft_TopBottom,
  3584. @"
  3585. 4 你 0
  3586. *******
  3587. *******
  3588. *******
  3589. *******
  3590. *******
  3591. *******")]
  3592. // RightLeft_BottomTop
  3593. [InlineData (
  3594. "0 2 4",
  3595. Alignment.Start,
  3596. Alignment.Start,
  3597. TextDirection.RightLeft_BottomTop,
  3598. @"
  3599. 4 2 0**
  3600. *******
  3601. *******
  3602. *******
  3603. *******
  3604. *******
  3605. *******")]
  3606. [InlineData (
  3607. "0 2 4",
  3608. Alignment.End,
  3609. Alignment.Start,
  3610. TextDirection.RightLeft_BottomTop,
  3611. @"
  3612. **4 2 0
  3613. *******
  3614. *******
  3615. *******
  3616. *******
  3617. *******
  3618. *******")]
  3619. [InlineData (
  3620. "0 2 4",
  3621. Alignment.Center,
  3622. Alignment.Start,
  3623. TextDirection.RightLeft_BottomTop,
  3624. @"
  3625. *4 2 0*
  3626. *******
  3627. *******
  3628. *******
  3629. *******
  3630. *******
  3631. *******")]
  3632. [InlineData (
  3633. "0 2 4",
  3634. Alignment.Fill,
  3635. Alignment.Start,
  3636. TextDirection.RightLeft_BottomTop,
  3637. @"
  3638. 4 2 0
  3639. *******
  3640. *******
  3641. *******
  3642. *******
  3643. *******
  3644. *******")]
  3645. [InlineData (
  3646. "0 你 4",
  3647. Alignment.Start,
  3648. Alignment.Start,
  3649. TextDirection.RightLeft_BottomTop,
  3650. @"
  3651. 4 你 0*
  3652. *******
  3653. *******
  3654. *******
  3655. *******
  3656. *******
  3657. *******")]
  3658. [InlineData (
  3659. "0 你 4",
  3660. Alignment.End,
  3661. Alignment.Start,
  3662. TextDirection.RightLeft_BottomTop,
  3663. @"
  3664. *4 你 0
  3665. *******
  3666. *******
  3667. *******
  3668. *******
  3669. *******
  3670. *******")]
  3671. [InlineData (
  3672. "0 你 4",
  3673. Alignment.Center,
  3674. Alignment.Start,
  3675. TextDirection.RightLeft_BottomTop,
  3676. @"
  3677. 4 你 0*
  3678. *******
  3679. *******
  3680. *******
  3681. *******
  3682. *******
  3683. *******")]
  3684. [InlineData (
  3685. "0 你 4",
  3686. Alignment.Fill,
  3687. Alignment.Start,
  3688. TextDirection.RightLeft_BottomTop,
  3689. @"
  3690. 4 你 0
  3691. *******
  3692. *******
  3693. *******
  3694. *******
  3695. *******
  3696. *******")]
  3697. // Horizontal with Alignment.End
  3698. // LeftRight_TopBottom
  3699. [InlineData (
  3700. "0 2 4",
  3701. Alignment.Start,
  3702. Alignment.End,
  3703. TextDirection.LeftRight_TopBottom,
  3704. @"
  3705. *******
  3706. *******
  3707. *******
  3708. *******
  3709. *******
  3710. *******
  3711. 0 2 4**")]
  3712. [InlineData (
  3713. "0 2 4",
  3714. Alignment.End,
  3715. Alignment.End,
  3716. TextDirection.LeftRight_TopBottom,
  3717. @"
  3718. *******
  3719. *******
  3720. *******
  3721. *******
  3722. *******
  3723. *******
  3724. **0 2 4")]
  3725. [InlineData (
  3726. "0 2 4",
  3727. Alignment.Center,
  3728. Alignment.End,
  3729. TextDirection.LeftRight_TopBottom,
  3730. @"
  3731. *******
  3732. *******
  3733. *******
  3734. *******
  3735. *******
  3736. *******
  3737. *0 2 4*")]
  3738. [InlineData (
  3739. "0 2 4",
  3740. Alignment.Fill,
  3741. Alignment.End,
  3742. TextDirection.LeftRight_TopBottom,
  3743. @"
  3744. *******
  3745. *******
  3746. *******
  3747. *******
  3748. *******
  3749. *******
  3750. 0 2 4")]
  3751. [InlineData (
  3752. "0 你 4",
  3753. Alignment.Start,
  3754. Alignment.End,
  3755. TextDirection.LeftRight_TopBottom,
  3756. @"
  3757. *******
  3758. *******
  3759. *******
  3760. *******
  3761. *******
  3762. *******
  3763. 0 你 4*")]
  3764. [InlineData (
  3765. "0 你 4",
  3766. Alignment.End,
  3767. Alignment.End,
  3768. TextDirection.LeftRight_TopBottom,
  3769. @"
  3770. *******
  3771. *******
  3772. *******
  3773. *******
  3774. *******
  3775. *******
  3776. *0 你 4")]
  3777. [InlineData (
  3778. "0 你 4",
  3779. Alignment.Center,
  3780. Alignment.End,
  3781. TextDirection.LeftRight_TopBottom,
  3782. @"
  3783. *******
  3784. *******
  3785. *******
  3786. *******
  3787. *******
  3788. *******
  3789. 0 你 4*")]
  3790. [InlineData (
  3791. "0 你 4",
  3792. Alignment.Fill,
  3793. Alignment.End,
  3794. TextDirection.LeftRight_TopBottom,
  3795. @"
  3796. *******
  3797. *******
  3798. *******
  3799. *******
  3800. *******
  3801. *******
  3802. 0 你 4")]
  3803. // LeftRight_BottomTop
  3804. [InlineData (
  3805. "0 2 4",
  3806. Alignment.Start,
  3807. Alignment.End,
  3808. TextDirection.LeftRight_BottomTop,
  3809. @"
  3810. *******
  3811. *******
  3812. *******
  3813. *******
  3814. *******
  3815. *******
  3816. 0 2 4**")]
  3817. [InlineData (
  3818. "0 2 4",
  3819. Alignment.End,
  3820. Alignment.End,
  3821. TextDirection.LeftRight_BottomTop,
  3822. @"
  3823. *******
  3824. *******
  3825. *******
  3826. *******
  3827. *******
  3828. *******
  3829. **0 2 4")]
  3830. [InlineData (
  3831. "0 2 4",
  3832. Alignment.Center,
  3833. Alignment.End,
  3834. TextDirection.LeftRight_BottomTop,
  3835. @"
  3836. *******
  3837. *******
  3838. *******
  3839. *******
  3840. *******
  3841. *******
  3842. *0 2 4*")]
  3843. [InlineData (
  3844. "0 2 4",
  3845. Alignment.Fill,
  3846. Alignment.End,
  3847. TextDirection.LeftRight_BottomTop,
  3848. @"
  3849. *******
  3850. *******
  3851. *******
  3852. *******
  3853. *******
  3854. *******
  3855. 0 2 4")]
  3856. [InlineData (
  3857. "0 你 4",
  3858. Alignment.Start,
  3859. Alignment.End,
  3860. TextDirection.LeftRight_BottomTop,
  3861. @"
  3862. *******
  3863. *******
  3864. *******
  3865. *******
  3866. *******
  3867. *******
  3868. 0 你 4*")]
  3869. [InlineData (
  3870. "0 你 4",
  3871. Alignment.End,
  3872. Alignment.End,
  3873. TextDirection.LeftRight_BottomTop,
  3874. @"
  3875. *******
  3876. *******
  3877. *******
  3878. *******
  3879. *******
  3880. *******
  3881. *0 你 4")]
  3882. [InlineData (
  3883. "0 你 4",
  3884. Alignment.Center,
  3885. Alignment.End,
  3886. TextDirection.LeftRight_BottomTop,
  3887. @"
  3888. *******
  3889. *******
  3890. *******
  3891. *******
  3892. *******
  3893. *******
  3894. 0 你 4*")]
  3895. [InlineData (
  3896. "0 你 4",
  3897. Alignment.Fill,
  3898. Alignment.End,
  3899. TextDirection.LeftRight_BottomTop,
  3900. @"
  3901. *******
  3902. *******
  3903. *******
  3904. *******
  3905. *******
  3906. *******
  3907. 0 你 4")]
  3908. // RightLeft_TopBottom
  3909. [InlineData (
  3910. "0 2 4",
  3911. Alignment.Start,
  3912. Alignment.End,
  3913. TextDirection.RightLeft_TopBottom,
  3914. @"
  3915. *******
  3916. *******
  3917. *******
  3918. *******
  3919. *******
  3920. *******
  3921. 4 2 0**")]
  3922. [InlineData (
  3923. "0 2 4",
  3924. Alignment.End,
  3925. Alignment.End,
  3926. TextDirection.RightLeft_TopBottom,
  3927. @"
  3928. *******
  3929. *******
  3930. *******
  3931. *******
  3932. *******
  3933. *******
  3934. **4 2 0")]
  3935. [InlineData (
  3936. "0 2 4",
  3937. Alignment.Center,
  3938. Alignment.End,
  3939. TextDirection.RightLeft_TopBottom,
  3940. @"
  3941. *******
  3942. *******
  3943. *******
  3944. *******
  3945. *******
  3946. *******
  3947. *4 2 0*")]
  3948. [InlineData (
  3949. "0 2 4",
  3950. Alignment.Fill,
  3951. Alignment.End,
  3952. TextDirection.RightLeft_TopBottom,
  3953. @"
  3954. *******
  3955. *******
  3956. *******
  3957. *******
  3958. *******
  3959. *******
  3960. 4 2 0")]
  3961. [InlineData (
  3962. "0 你 4",
  3963. Alignment.Start,
  3964. Alignment.End,
  3965. TextDirection.RightLeft_TopBottom,
  3966. @"
  3967. *******
  3968. *******
  3969. *******
  3970. *******
  3971. *******
  3972. *******
  3973. 4 你 0*")]
  3974. [InlineData (
  3975. "0 你 4",
  3976. Alignment.End,
  3977. Alignment.End,
  3978. TextDirection.RightLeft_TopBottom,
  3979. @"
  3980. *******
  3981. *******
  3982. *******
  3983. *******
  3984. *******
  3985. *******
  3986. *4 你 0")]
  3987. [InlineData (
  3988. "0 你 4",
  3989. Alignment.Center,
  3990. Alignment.End,
  3991. TextDirection.RightLeft_TopBottom,
  3992. @"
  3993. *******
  3994. *******
  3995. *******
  3996. *******
  3997. *******
  3998. *******
  3999. 4 你 0*")]
  4000. [InlineData (
  4001. "0 你 4",
  4002. Alignment.Fill,
  4003. Alignment.End,
  4004. TextDirection.RightLeft_TopBottom,
  4005. @"
  4006. *******
  4007. *******
  4008. *******
  4009. *******
  4010. *******
  4011. *******
  4012. 4 你 0")]
  4013. // RightLeft_BottomTop
  4014. [InlineData (
  4015. "0 2 4",
  4016. Alignment.Start,
  4017. Alignment.End,
  4018. TextDirection.RightLeft_BottomTop,
  4019. @"
  4020. *******
  4021. *******
  4022. *******
  4023. *******
  4024. *******
  4025. *******
  4026. 4 2 0**")]
  4027. [InlineData (
  4028. "0 2 4",
  4029. Alignment.End,
  4030. Alignment.End,
  4031. TextDirection.RightLeft_BottomTop,
  4032. @"
  4033. *******
  4034. *******
  4035. *******
  4036. *******
  4037. *******
  4038. *******
  4039. **4 2 0")]
  4040. [InlineData (
  4041. "0 2 4",
  4042. Alignment.Center,
  4043. Alignment.End,
  4044. TextDirection.RightLeft_BottomTop,
  4045. @"
  4046. *******
  4047. *******
  4048. *******
  4049. *******
  4050. *******
  4051. *******
  4052. *4 2 0*")]
  4053. [InlineData (
  4054. "0 2 4",
  4055. Alignment.Fill,
  4056. Alignment.End,
  4057. TextDirection.RightLeft_BottomTop,
  4058. @"
  4059. *******
  4060. *******
  4061. *******
  4062. *******
  4063. *******
  4064. *******
  4065. 4 2 0")]
  4066. [InlineData (
  4067. "0 你 4",
  4068. Alignment.Start,
  4069. Alignment.End,
  4070. TextDirection.RightLeft_BottomTop,
  4071. @"
  4072. *******
  4073. *******
  4074. *******
  4075. *******
  4076. *******
  4077. *******
  4078. 4 你 0*")]
  4079. [InlineData (
  4080. "0 你 4",
  4081. Alignment.End,
  4082. Alignment.End,
  4083. TextDirection.RightLeft_BottomTop,
  4084. @"
  4085. *******
  4086. *******
  4087. *******
  4088. *******
  4089. *******
  4090. *******
  4091. *4 你 0")]
  4092. [InlineData (
  4093. "0 你 4",
  4094. Alignment.Center,
  4095. Alignment.End,
  4096. TextDirection.RightLeft_BottomTop,
  4097. @"
  4098. *******
  4099. *******
  4100. *******
  4101. *******
  4102. *******
  4103. *******
  4104. 4 你 0*")]
  4105. [InlineData (
  4106. "0 你 4",
  4107. Alignment.Fill,
  4108. Alignment.End,
  4109. TextDirection.RightLeft_BottomTop,
  4110. @"
  4111. *******
  4112. *******
  4113. *******
  4114. *******
  4115. *******
  4116. *******
  4117. 4 你 0")]
  4118. // Horizontal with alignment.Centered
  4119. // LeftRight_TopBottom
  4120. [InlineData (
  4121. "0 2 4",
  4122. Alignment.Start,
  4123. Alignment.Center,
  4124. TextDirection.LeftRight_TopBottom,
  4125. @"
  4126. *******
  4127. *******
  4128. *******
  4129. 0 2 4**
  4130. *******
  4131. *******
  4132. *******")]
  4133. [InlineData (
  4134. "0 2 4",
  4135. Alignment.End,
  4136. Alignment.Center,
  4137. TextDirection.LeftRight_TopBottom,
  4138. @"
  4139. *******
  4140. *******
  4141. *******
  4142. **0 2 4
  4143. *******
  4144. *******
  4145. *******")]
  4146. [InlineData (
  4147. "0 2 4",
  4148. Alignment.Center,
  4149. Alignment.Center,
  4150. TextDirection.LeftRight_TopBottom,
  4151. @"
  4152. *******
  4153. *******
  4154. *******
  4155. *0 2 4*
  4156. *******
  4157. *******
  4158. *******")]
  4159. [InlineData (
  4160. "0 2 4",
  4161. Alignment.Fill,
  4162. Alignment.Center,
  4163. TextDirection.LeftRight_TopBottom,
  4164. @"
  4165. *******
  4166. *******
  4167. *******
  4168. 0 2 4
  4169. *******
  4170. *******
  4171. *******")]
  4172. [InlineData (
  4173. "0 你 4",
  4174. Alignment.Start,
  4175. Alignment.Center,
  4176. TextDirection.LeftRight_TopBottom,
  4177. @"
  4178. *******
  4179. *******
  4180. *******
  4181. 0 你 4*
  4182. *******
  4183. *******
  4184. *******")]
  4185. [InlineData (
  4186. "0 你 4",
  4187. Alignment.End,
  4188. Alignment.Center,
  4189. TextDirection.LeftRight_TopBottom,
  4190. @"
  4191. *******
  4192. *******
  4193. *******
  4194. *0 你 4
  4195. *******
  4196. *******
  4197. *******")]
  4198. [InlineData (
  4199. "0 你 4",
  4200. Alignment.Center,
  4201. Alignment.Center,
  4202. TextDirection.LeftRight_TopBottom,
  4203. @"
  4204. *******
  4205. *******
  4206. *******
  4207. 0 你 4*
  4208. *******
  4209. *******
  4210. *******")]
  4211. [InlineData (
  4212. "0 你 4",
  4213. Alignment.Fill,
  4214. Alignment.Center,
  4215. TextDirection.LeftRight_TopBottom,
  4216. @"
  4217. *******
  4218. *******
  4219. *******
  4220. 0 你 4
  4221. *******
  4222. *******
  4223. *******")]
  4224. // LeftRight_BottomTop
  4225. [InlineData (
  4226. "0 2 4",
  4227. Alignment.Start,
  4228. Alignment.Center,
  4229. TextDirection.LeftRight_BottomTop,
  4230. @"
  4231. *******
  4232. *******
  4233. *******
  4234. 0 2 4**
  4235. *******
  4236. *******
  4237. *******")]
  4238. [InlineData (
  4239. "0 2 4",
  4240. Alignment.End,
  4241. Alignment.Center,
  4242. TextDirection.LeftRight_BottomTop,
  4243. @"
  4244. *******
  4245. *******
  4246. *******
  4247. **0 2 4
  4248. *******
  4249. *******
  4250. *******")]
  4251. [InlineData (
  4252. "0 2 4",
  4253. Alignment.Center,
  4254. Alignment.Center,
  4255. TextDirection.LeftRight_BottomTop,
  4256. @"
  4257. *******
  4258. *******
  4259. *******
  4260. *0 2 4*
  4261. *******
  4262. *******
  4263. *******")]
  4264. [InlineData (
  4265. "0 2 4",
  4266. Alignment.Fill,
  4267. Alignment.Center,
  4268. TextDirection.LeftRight_BottomTop,
  4269. @"
  4270. *******
  4271. *******
  4272. *******
  4273. 0 2 4
  4274. *******
  4275. *******
  4276. *******")]
  4277. [InlineData (
  4278. "0 你 4",
  4279. Alignment.Start,
  4280. Alignment.Center,
  4281. TextDirection.LeftRight_BottomTop,
  4282. @"
  4283. *******
  4284. *******
  4285. *******
  4286. 0 你 4*
  4287. *******
  4288. *******
  4289. *******")]
  4290. [InlineData (
  4291. "0 你 4",
  4292. Alignment.End,
  4293. Alignment.Center,
  4294. TextDirection.LeftRight_BottomTop,
  4295. @"
  4296. *******
  4297. *******
  4298. *******
  4299. *0 你 4
  4300. *******
  4301. *******
  4302. *******")]
  4303. [InlineData (
  4304. "0 你 4",
  4305. Alignment.Center,
  4306. Alignment.Center,
  4307. TextDirection.LeftRight_BottomTop,
  4308. @"
  4309. *******
  4310. *******
  4311. *******
  4312. 0 你 4*
  4313. *******
  4314. *******
  4315. *******")]
  4316. [InlineData (
  4317. "0 你 4",
  4318. Alignment.Fill,
  4319. Alignment.Center,
  4320. TextDirection.LeftRight_BottomTop,
  4321. @"
  4322. *******
  4323. *******
  4324. *******
  4325. 0 你 4
  4326. *******
  4327. *******
  4328. *******")]
  4329. // RightLeft_TopBottom
  4330. [InlineData (
  4331. "0 2 4",
  4332. Alignment.Start,
  4333. Alignment.Center,
  4334. TextDirection.RightLeft_TopBottom,
  4335. @"
  4336. *******
  4337. *******
  4338. *******
  4339. 4 2 0**
  4340. *******
  4341. *******
  4342. *******")]
  4343. [InlineData (
  4344. "0 2 4",
  4345. Alignment.End,
  4346. Alignment.Center,
  4347. TextDirection.RightLeft_TopBottom,
  4348. @"
  4349. *******
  4350. *******
  4351. *******
  4352. **4 2 0
  4353. *******
  4354. *******
  4355. *******")]
  4356. [InlineData (
  4357. "0 2 4",
  4358. Alignment.Center,
  4359. Alignment.Center,
  4360. TextDirection.RightLeft_TopBottom,
  4361. @"
  4362. *******
  4363. *******
  4364. *******
  4365. *4 2 0*
  4366. *******
  4367. *******
  4368. *******")]
  4369. [InlineData (
  4370. "0 2 4",
  4371. Alignment.Fill,
  4372. Alignment.Center,
  4373. TextDirection.RightLeft_TopBottom,
  4374. @"
  4375. *******
  4376. *******
  4377. *******
  4378. 4 2 0
  4379. *******
  4380. *******
  4381. *******")]
  4382. [InlineData (
  4383. "0 你 4",
  4384. Alignment.Start,
  4385. Alignment.Center,
  4386. TextDirection.RightLeft_TopBottom,
  4387. @"
  4388. *******
  4389. *******
  4390. *******
  4391. 4 你 0*
  4392. *******
  4393. *******
  4394. *******")]
  4395. [InlineData (
  4396. "0 你 4",
  4397. Alignment.End,
  4398. Alignment.Center,
  4399. TextDirection.RightLeft_TopBottom,
  4400. @"
  4401. *******
  4402. *******
  4403. *******
  4404. *4 你 0
  4405. *******
  4406. *******
  4407. *******")]
  4408. [InlineData (
  4409. "0 你 4",
  4410. Alignment.Center,
  4411. Alignment.Center,
  4412. TextDirection.RightLeft_TopBottom,
  4413. @"
  4414. *******
  4415. *******
  4416. *******
  4417. 4 你 0*
  4418. *******
  4419. *******
  4420. *******")]
  4421. [InlineData (
  4422. "0 你 4",
  4423. Alignment.Fill,
  4424. Alignment.Center,
  4425. TextDirection.RightLeft_TopBottom,
  4426. @"
  4427. *******
  4428. *******
  4429. *******
  4430. 4 你 0
  4431. *******
  4432. *******
  4433. *******")]
  4434. // RightLeft_BottomTop
  4435. [InlineData (
  4436. "0 2 4",
  4437. Alignment.Start,
  4438. Alignment.Center,
  4439. TextDirection.RightLeft_BottomTop,
  4440. @"
  4441. *******
  4442. *******
  4443. *******
  4444. 4 2 0**
  4445. *******
  4446. *******
  4447. *******")]
  4448. [InlineData (
  4449. "0 2 4",
  4450. Alignment.End,
  4451. Alignment.Center,
  4452. TextDirection.RightLeft_BottomTop,
  4453. @"
  4454. *******
  4455. *******
  4456. *******
  4457. **4 2 0
  4458. *******
  4459. *******
  4460. *******")]
  4461. [InlineData (
  4462. "0 2 4",
  4463. Alignment.Center,
  4464. Alignment.Center,
  4465. TextDirection.RightLeft_BottomTop,
  4466. @"
  4467. *******
  4468. *******
  4469. *******
  4470. *4 2 0*
  4471. *******
  4472. *******
  4473. *******")]
  4474. [InlineData (
  4475. "0 2 4",
  4476. Alignment.Fill,
  4477. Alignment.Center,
  4478. TextDirection.RightLeft_BottomTop,
  4479. @"
  4480. *******
  4481. *******
  4482. *******
  4483. 4 2 0
  4484. *******
  4485. *******
  4486. *******")]
  4487. [InlineData (
  4488. "0 你 4",
  4489. Alignment.Start,
  4490. Alignment.Center,
  4491. TextDirection.RightLeft_BottomTop,
  4492. @"
  4493. *******
  4494. *******
  4495. *******
  4496. 4 你 0*
  4497. *******
  4498. *******
  4499. *******")]
  4500. [InlineData (
  4501. "0 你 4",
  4502. Alignment.End,
  4503. Alignment.Center,
  4504. TextDirection.RightLeft_BottomTop,
  4505. @"
  4506. *******
  4507. *******
  4508. *******
  4509. *4 你 0
  4510. *******
  4511. *******
  4512. *******")]
  4513. [InlineData (
  4514. "0 你 4",
  4515. Alignment.Center,
  4516. Alignment.Center,
  4517. TextDirection.RightLeft_BottomTop,
  4518. @"
  4519. *******
  4520. *******
  4521. *******
  4522. 4 你 0*
  4523. *******
  4524. *******
  4525. *******")]
  4526. [InlineData (
  4527. "0 你 4",
  4528. Alignment.Fill,
  4529. Alignment.Center,
  4530. TextDirection.RightLeft_BottomTop,
  4531. @"
  4532. *******
  4533. *******
  4534. *******
  4535. 4 你 0
  4536. *******
  4537. *******
  4538. *******")]
  4539. // Horizontal with alignment.Justified
  4540. // LeftRight_TopBottom
  4541. [InlineData (
  4542. "0 2 4",
  4543. Alignment.Start,
  4544. Alignment.Fill,
  4545. TextDirection.LeftRight_TopBottom,
  4546. @"
  4547. 0 2 4**
  4548. *******
  4549. *******
  4550. *******
  4551. *******
  4552. *******
  4553. *******")]
  4554. [InlineData (
  4555. "0 2 4",
  4556. Alignment.End,
  4557. Alignment.Fill,
  4558. TextDirection.LeftRight_TopBottom,
  4559. @"
  4560. **0 2 4
  4561. *******
  4562. *******
  4563. *******
  4564. *******
  4565. *******
  4566. *******")]
  4567. [InlineData (
  4568. "0 2 4",
  4569. Alignment.Center,
  4570. Alignment.Fill,
  4571. TextDirection.LeftRight_TopBottom,
  4572. @"
  4573. *0 2 4*
  4574. *******
  4575. *******
  4576. *******
  4577. *******
  4578. *******
  4579. *******")]
  4580. [InlineData (
  4581. "0 2 4",
  4582. Alignment.Fill,
  4583. Alignment.Fill,
  4584. TextDirection.LeftRight_TopBottom,
  4585. @"
  4586. 0 2 4
  4587. *******
  4588. *******
  4589. *******
  4590. *******
  4591. *******
  4592. *******")]
  4593. [InlineData (
  4594. "0 你 4",
  4595. Alignment.Start,
  4596. Alignment.Fill,
  4597. TextDirection.LeftRight_TopBottom,
  4598. @"
  4599. 0 你 4*
  4600. *******
  4601. *******
  4602. *******
  4603. *******
  4604. *******
  4605. *******")]
  4606. [InlineData (
  4607. "0 你 4",
  4608. Alignment.End,
  4609. Alignment.Fill,
  4610. TextDirection.LeftRight_TopBottom,
  4611. @"
  4612. *0 你 4
  4613. *******
  4614. *******
  4615. *******
  4616. *******
  4617. *******
  4618. *******")]
  4619. [InlineData (
  4620. "0 你 4",
  4621. Alignment.Center,
  4622. Alignment.Fill,
  4623. TextDirection.LeftRight_TopBottom,
  4624. @"
  4625. 0 你 4*
  4626. *******
  4627. *******
  4628. *******
  4629. *******
  4630. *******
  4631. *******")]
  4632. [InlineData (
  4633. "0 你 4",
  4634. Alignment.Fill,
  4635. Alignment.Fill,
  4636. TextDirection.LeftRight_TopBottom,
  4637. @"
  4638. 0 你 4
  4639. *******
  4640. *******
  4641. *******
  4642. *******
  4643. *******
  4644. *******")]
  4645. // LeftRight_BottomTop
  4646. [InlineData (
  4647. "0 2 4",
  4648. Alignment.Start,
  4649. Alignment.Fill,
  4650. TextDirection.LeftRight_BottomTop,
  4651. @"
  4652. 0 2 4**
  4653. *******
  4654. *******
  4655. *******
  4656. *******
  4657. *******
  4658. *******")]
  4659. [InlineData (
  4660. "0 2 4",
  4661. Alignment.End,
  4662. Alignment.Fill,
  4663. TextDirection.LeftRight_BottomTop,
  4664. @"
  4665. **0 2 4
  4666. *******
  4667. *******
  4668. *******
  4669. *******
  4670. *******
  4671. *******")]
  4672. [InlineData (
  4673. "0 2 4",
  4674. Alignment.Center,
  4675. Alignment.Fill,
  4676. TextDirection.LeftRight_BottomTop,
  4677. @"
  4678. *0 2 4*
  4679. *******
  4680. *******
  4681. *******
  4682. *******
  4683. *******
  4684. *******")]
  4685. [InlineData (
  4686. "0 2 4",
  4687. Alignment.Fill,
  4688. Alignment.Fill,
  4689. TextDirection.LeftRight_BottomTop,
  4690. @"
  4691. 0 2 4
  4692. *******
  4693. *******
  4694. *******
  4695. *******
  4696. *******
  4697. *******")]
  4698. [InlineData (
  4699. "0 你 4",
  4700. Alignment.Start,
  4701. Alignment.Fill,
  4702. TextDirection.LeftRight_BottomTop,
  4703. @"
  4704. 0 你 4*
  4705. *******
  4706. *******
  4707. *******
  4708. *******
  4709. *******
  4710. *******")]
  4711. [InlineData (
  4712. "0 你 4",
  4713. Alignment.End,
  4714. Alignment.Fill,
  4715. TextDirection.LeftRight_BottomTop,
  4716. @"
  4717. *0 你 4
  4718. *******
  4719. *******
  4720. *******
  4721. *******
  4722. *******
  4723. *******")]
  4724. [InlineData (
  4725. "0 你 4",
  4726. Alignment.Center,
  4727. Alignment.Fill,
  4728. TextDirection.LeftRight_BottomTop,
  4729. @"
  4730. 0 你 4*
  4731. *******
  4732. *******
  4733. *******
  4734. *******
  4735. *******
  4736. *******")]
  4737. [InlineData (
  4738. "0 你 4",
  4739. Alignment.Fill,
  4740. Alignment.Fill,
  4741. TextDirection.LeftRight_BottomTop,
  4742. @"
  4743. 0 你 4
  4744. *******
  4745. *******
  4746. *******
  4747. *******
  4748. *******
  4749. *******")]
  4750. // RightLeft_TopBottom
  4751. [InlineData (
  4752. "0 2 4",
  4753. Alignment.Start,
  4754. Alignment.Fill,
  4755. TextDirection.RightLeft_TopBottom,
  4756. @"
  4757. 4 2 0**
  4758. *******
  4759. *******
  4760. *******
  4761. *******
  4762. *******
  4763. *******")]
  4764. [InlineData (
  4765. "0 2 4",
  4766. Alignment.End,
  4767. Alignment.Fill,
  4768. TextDirection.RightLeft_TopBottom,
  4769. @"
  4770. **4 2 0
  4771. *******
  4772. *******
  4773. *******
  4774. *******
  4775. *******
  4776. *******")]
  4777. [InlineData (
  4778. "0 2 4",
  4779. Alignment.Center,
  4780. Alignment.Fill,
  4781. TextDirection.RightLeft_TopBottom,
  4782. @"
  4783. *4 2 0*
  4784. *******
  4785. *******
  4786. *******
  4787. *******
  4788. *******
  4789. *******")]
  4790. [InlineData (
  4791. "0 2 4",
  4792. Alignment.Fill,
  4793. Alignment.Fill,
  4794. TextDirection.RightLeft_TopBottom,
  4795. @"
  4796. 4 2 0
  4797. *******
  4798. *******
  4799. *******
  4800. *******
  4801. *******
  4802. *******")]
  4803. [InlineData (
  4804. "0 你 4",
  4805. Alignment.Start,
  4806. Alignment.Fill,
  4807. TextDirection.RightLeft_TopBottom,
  4808. @"
  4809. 4 你 0*
  4810. *******
  4811. *******
  4812. *******
  4813. *******
  4814. *******
  4815. *******")]
  4816. [InlineData (
  4817. "0 你 4",
  4818. Alignment.End,
  4819. Alignment.Fill,
  4820. TextDirection.RightLeft_TopBottom,
  4821. @"
  4822. *4 你 0
  4823. *******
  4824. *******
  4825. *******
  4826. *******
  4827. *******
  4828. *******")]
  4829. [InlineData (
  4830. "0 你 4",
  4831. Alignment.Center,
  4832. Alignment.Fill,
  4833. TextDirection.RightLeft_TopBottom,
  4834. @"
  4835. 4 你 0*
  4836. *******
  4837. *******
  4838. *******
  4839. *******
  4840. *******
  4841. *******")]
  4842. [InlineData (
  4843. "0 你 4",
  4844. Alignment.Fill,
  4845. Alignment.Fill,
  4846. TextDirection.RightLeft_TopBottom,
  4847. @"
  4848. 4 你 0
  4849. *******
  4850. *******
  4851. *******
  4852. *******
  4853. *******
  4854. *******")]
  4855. // RightLeft_BottomTop
  4856. [InlineData (
  4857. "0 2 4",
  4858. Alignment.Start,
  4859. Alignment.Fill,
  4860. TextDirection.RightLeft_BottomTop,
  4861. @"
  4862. 4 2 0**
  4863. *******
  4864. *******
  4865. *******
  4866. *******
  4867. *******
  4868. *******")]
  4869. [InlineData (
  4870. "0 2 4",
  4871. Alignment.End,
  4872. Alignment.Fill,
  4873. TextDirection.RightLeft_BottomTop,
  4874. @"
  4875. **4 2 0
  4876. *******
  4877. *******
  4878. *******
  4879. *******
  4880. *******
  4881. *******")]
  4882. [InlineData (
  4883. "0 2 4",
  4884. Alignment.Center,
  4885. Alignment.Fill,
  4886. TextDirection.RightLeft_BottomTop,
  4887. @"
  4888. *4 2 0*
  4889. *******
  4890. *******
  4891. *******
  4892. *******
  4893. *******
  4894. *******")]
  4895. [InlineData (
  4896. "0 2 4",
  4897. Alignment.Fill,
  4898. Alignment.Fill,
  4899. TextDirection.RightLeft_BottomTop,
  4900. @"
  4901. 4 2 0
  4902. *******
  4903. *******
  4904. *******
  4905. *******
  4906. *******
  4907. *******")]
  4908. [InlineData (
  4909. "0 你 4",
  4910. Alignment.Start,
  4911. Alignment.Fill,
  4912. TextDirection.RightLeft_BottomTop,
  4913. @"
  4914. 4 你 0*
  4915. *******
  4916. *******
  4917. *******
  4918. *******
  4919. *******
  4920. *******")]
  4921. [InlineData (
  4922. "0 你 4",
  4923. Alignment.End,
  4924. Alignment.Fill,
  4925. TextDirection.RightLeft_BottomTop,
  4926. @"
  4927. *4 你 0
  4928. *******
  4929. *******
  4930. *******
  4931. *******
  4932. *******
  4933. *******")]
  4934. [InlineData (
  4935. "0 你 4",
  4936. Alignment.Center,
  4937. Alignment.Fill,
  4938. TextDirection.RightLeft_BottomTop,
  4939. @"
  4940. 4 你 0*
  4941. *******
  4942. *******
  4943. *******
  4944. *******
  4945. *******
  4946. *******")]
  4947. [InlineData (
  4948. "0 你 4",
  4949. Alignment.Fill,
  4950. Alignment.Fill,
  4951. TextDirection.RightLeft_BottomTop,
  4952. @"
  4953. 4 你 0
  4954. *******
  4955. *******
  4956. *******
  4957. *******
  4958. *******
  4959. *******")]
  4960. // Vertical with alignment.Left
  4961. // TopBottom_LeftRight
  4962. [InlineData (
  4963. "0 2 4",
  4964. Alignment.Start,
  4965. Alignment.Start,
  4966. TextDirection.TopBottom_LeftRight,
  4967. @"
  4968. 0******
  4969. ******
  4970. 2******
  4971. ******
  4972. 4******
  4973. *******
  4974. *******")]
  4975. [InlineData (
  4976. "0 2 4",
  4977. Alignment.Start,
  4978. Alignment.End,
  4979. TextDirection.TopBottom_LeftRight,
  4980. @"
  4981. *******
  4982. *******
  4983. 0******
  4984. ******
  4985. 2******
  4986. ******
  4987. 4******")]
  4988. [InlineData (
  4989. "0 2 4",
  4990. Alignment.Start,
  4991. Alignment.Center,
  4992. TextDirection.TopBottom_LeftRight,
  4993. @"
  4994. *******
  4995. 0******
  4996. ******
  4997. 2******
  4998. ******
  4999. 4******
  5000. *******")]
  5001. [InlineData (
  5002. "0 2 4",
  5003. Alignment.Start,
  5004. Alignment.Fill,
  5005. TextDirection.TopBottom_LeftRight,
  5006. @"
  5007. 0******
  5008. ******
  5009. ******
  5010. 2******
  5011. ******
  5012. ******
  5013. 4******")]
  5014. [InlineData (
  5015. "0 你 4",
  5016. Alignment.Start,
  5017. Alignment.Start,
  5018. TextDirection.TopBottom_LeftRight,
  5019. @"
  5020. 0******
  5021. ******
  5022. 你*****
  5023. ******
  5024. 4******
  5025. *******
  5026. *******")]
  5027. [InlineData (
  5028. "0 你 4",
  5029. Alignment.Start,
  5030. Alignment.End,
  5031. TextDirection.TopBottom_LeftRight,
  5032. @"
  5033. *******
  5034. *******
  5035. 0******
  5036. ******
  5037. 你*****
  5038. ******
  5039. 4******")]
  5040. [InlineData (
  5041. "0 你 4",
  5042. Alignment.Start,
  5043. Alignment.Center,
  5044. TextDirection.TopBottom_LeftRight,
  5045. @"
  5046. *******
  5047. 0******
  5048. ******
  5049. 你*****
  5050. ******
  5051. 4******
  5052. *******")]
  5053. [InlineData (
  5054. "0 你 4",
  5055. Alignment.Start,
  5056. Alignment.Fill,
  5057. TextDirection.TopBottom_LeftRight,
  5058. @"
  5059. 0******
  5060. ******
  5061. ******
  5062. 你*****
  5063. ******
  5064. ******
  5065. 4******")]
  5066. // TopBottom_RightLeft
  5067. [InlineData (
  5068. "0 2 4",
  5069. Alignment.Start,
  5070. Alignment.Start,
  5071. TextDirection.TopBottom_RightLeft,
  5072. @"
  5073. 0******
  5074. ******
  5075. 2******
  5076. ******
  5077. 4******
  5078. *******
  5079. *******")]
  5080. [InlineData (
  5081. "0 2 4",
  5082. Alignment.Start,
  5083. Alignment.End,
  5084. TextDirection.TopBottom_RightLeft,
  5085. @"
  5086. *******
  5087. *******
  5088. 0******
  5089. ******
  5090. 2******
  5091. ******
  5092. 4******")]
  5093. [InlineData (
  5094. "0 2 4",
  5095. Alignment.Start,
  5096. Alignment.Center,
  5097. TextDirection.TopBottom_RightLeft,
  5098. @"
  5099. *******
  5100. 0******
  5101. ******
  5102. 2******
  5103. ******
  5104. 4******
  5105. *******")]
  5106. [InlineData (
  5107. "0 2 4",
  5108. Alignment.Start,
  5109. Alignment.Fill,
  5110. TextDirection.TopBottom_RightLeft,
  5111. @"
  5112. 0******
  5113. ******
  5114. ******
  5115. 2******
  5116. ******
  5117. ******
  5118. 4******")]
  5119. [InlineData (
  5120. "0 你 4",
  5121. Alignment.Start,
  5122. Alignment.Start,
  5123. TextDirection.TopBottom_RightLeft,
  5124. @"
  5125. 0******
  5126. ******
  5127. 你*****
  5128. ******
  5129. 4******
  5130. *******
  5131. *******")]
  5132. [InlineData (
  5133. "0 你 4",
  5134. Alignment.Start,
  5135. Alignment.End,
  5136. TextDirection.TopBottom_RightLeft,
  5137. @"
  5138. *******
  5139. *******
  5140. 0******
  5141. ******
  5142. 你*****
  5143. ******
  5144. 4******")]
  5145. [InlineData (
  5146. "0 你 4",
  5147. Alignment.Start,
  5148. Alignment.Center,
  5149. TextDirection.TopBottom_RightLeft,
  5150. @"
  5151. *******
  5152. 0******
  5153. ******
  5154. 你*****
  5155. ******
  5156. 4******
  5157. *******")]
  5158. [InlineData (
  5159. "0 你 4",
  5160. Alignment.Start,
  5161. Alignment.Fill,
  5162. TextDirection.TopBottom_RightLeft,
  5163. @"
  5164. 0******
  5165. ******
  5166. ******
  5167. 你*****
  5168. ******
  5169. ******
  5170. 4******")]
  5171. // BottomTop_LeftRight
  5172. [InlineData (
  5173. "0 2 4",
  5174. Alignment.Start,
  5175. Alignment.Start,
  5176. TextDirection.BottomTop_LeftRight,
  5177. @"
  5178. 4******
  5179. ******
  5180. 2******
  5181. ******
  5182. 0******
  5183. *******
  5184. *******")]
  5185. [InlineData (
  5186. "0 2 4",
  5187. Alignment.Start,
  5188. Alignment.End,
  5189. TextDirection.BottomTop_LeftRight,
  5190. @"
  5191. *******
  5192. *******
  5193. 4******
  5194. ******
  5195. 2******
  5196. ******
  5197. 0******")]
  5198. [InlineData (
  5199. "0 2 4",
  5200. Alignment.Start,
  5201. Alignment.Center,
  5202. TextDirection.BottomTop_LeftRight,
  5203. @"
  5204. *******
  5205. 4******
  5206. ******
  5207. 2******
  5208. ******
  5209. 0******
  5210. *******")]
  5211. [InlineData (
  5212. "0 2 4",
  5213. Alignment.Start,
  5214. Alignment.Fill,
  5215. TextDirection.BottomTop_LeftRight,
  5216. @"
  5217. 4******
  5218. ******
  5219. ******
  5220. 2******
  5221. ******
  5222. ******
  5223. 0******")]
  5224. [InlineData (
  5225. "0 你 4",
  5226. Alignment.Start,
  5227. Alignment.Start,
  5228. TextDirection.BottomTop_LeftRight,
  5229. @"
  5230. 4******
  5231. ******
  5232. 你*****
  5233. ******
  5234. 0******
  5235. *******
  5236. *******")]
  5237. [InlineData (
  5238. "0 你 4",
  5239. Alignment.Start,
  5240. Alignment.End,
  5241. TextDirection.BottomTop_LeftRight,
  5242. @"
  5243. *******
  5244. *******
  5245. 4******
  5246. ******
  5247. 你*****
  5248. ******
  5249. 0******")]
  5250. [InlineData (
  5251. "0 你 4",
  5252. Alignment.Start,
  5253. Alignment.Center,
  5254. TextDirection.BottomTop_LeftRight,
  5255. @"
  5256. *******
  5257. 4******
  5258. ******
  5259. 你*****
  5260. ******
  5261. 0******
  5262. *******")]
  5263. [InlineData (
  5264. "0 你 4",
  5265. Alignment.Start,
  5266. Alignment.Fill,
  5267. TextDirection.BottomTop_LeftRight,
  5268. @"
  5269. 4******
  5270. ******
  5271. ******
  5272. 你*****
  5273. ******
  5274. ******
  5275. 0******")]
  5276. // BottomTop_RightLeft
  5277. [InlineData (
  5278. "0 2 4",
  5279. Alignment.Start,
  5280. Alignment.Start,
  5281. TextDirection.BottomTop_RightLeft,
  5282. @"
  5283. 4******
  5284. ******
  5285. 2******
  5286. ******
  5287. 0******
  5288. *******
  5289. *******")]
  5290. [InlineData (
  5291. "0 2 4",
  5292. Alignment.Start,
  5293. Alignment.End,
  5294. TextDirection.BottomTop_RightLeft,
  5295. @"
  5296. *******
  5297. *******
  5298. 4******
  5299. ******
  5300. 2******
  5301. ******
  5302. 0******")]
  5303. [InlineData (
  5304. "0 2 4",
  5305. Alignment.Start,
  5306. Alignment.Center,
  5307. TextDirection.BottomTop_RightLeft,
  5308. @"
  5309. *******
  5310. 4******
  5311. ******
  5312. 2******
  5313. ******
  5314. 0******
  5315. *******")]
  5316. [InlineData (
  5317. "0 2 4",
  5318. Alignment.Start,
  5319. Alignment.Fill,
  5320. TextDirection.BottomTop_RightLeft,
  5321. @"
  5322. 4******
  5323. ******
  5324. ******
  5325. 2******
  5326. ******
  5327. ******
  5328. 0******")]
  5329. [InlineData (
  5330. "0 你 4",
  5331. Alignment.Start,
  5332. Alignment.Start,
  5333. TextDirection.BottomTop_RightLeft,
  5334. @"
  5335. 4******
  5336. ******
  5337. 你*****
  5338. ******
  5339. 0******
  5340. *******
  5341. *******")]
  5342. [InlineData (
  5343. "0 你 4",
  5344. Alignment.Start,
  5345. Alignment.End,
  5346. TextDirection.BottomTop_RightLeft,
  5347. @"
  5348. *******
  5349. *******
  5350. 4******
  5351. ******
  5352. 你*****
  5353. ******
  5354. 0******")]
  5355. [InlineData (
  5356. "0 你 4",
  5357. Alignment.Start,
  5358. Alignment.Center,
  5359. TextDirection.BottomTop_RightLeft,
  5360. @"
  5361. *******
  5362. 4******
  5363. ******
  5364. 你*****
  5365. ******
  5366. 0******
  5367. *******")]
  5368. [InlineData (
  5369. "0 你 4",
  5370. Alignment.Start,
  5371. Alignment.Fill,
  5372. TextDirection.BottomTop_RightLeft,
  5373. @"
  5374. 4******
  5375. ******
  5376. ******
  5377. 你*****
  5378. ******
  5379. ******
  5380. 0******")]
  5381. // Vertical with alignment.Right
  5382. // TopBottom_LeftRight
  5383. [InlineData (
  5384. "0 2 4",
  5385. Alignment.End,
  5386. Alignment.Start,
  5387. TextDirection.TopBottom_LeftRight,
  5388. @"
  5389. ******0
  5390. ******
  5391. ******2
  5392. ******
  5393. ******4
  5394. *******
  5395. *******")]
  5396. [InlineData (
  5397. "0 2 4",
  5398. Alignment.End,
  5399. Alignment.End,
  5400. TextDirection.TopBottom_LeftRight,
  5401. @"
  5402. *******
  5403. *******
  5404. ******0
  5405. ******
  5406. ******2
  5407. ******
  5408. ******4")]
  5409. [InlineData (
  5410. "0 2 4",
  5411. Alignment.End,
  5412. Alignment.Center,
  5413. TextDirection.TopBottom_LeftRight,
  5414. @"
  5415. *******
  5416. ******0
  5417. ******
  5418. ******2
  5419. ******
  5420. ******4
  5421. *******")]
  5422. [InlineData (
  5423. "0 2 4",
  5424. Alignment.End,
  5425. Alignment.Fill,
  5426. TextDirection.TopBottom_LeftRight,
  5427. @"
  5428. ******0
  5429. ******
  5430. ******
  5431. ******2
  5432. ******
  5433. ******
  5434. ******4")]
  5435. [InlineData (
  5436. "0 你 4",
  5437. Alignment.End,
  5438. Alignment.Start,
  5439. TextDirection.TopBottom_LeftRight,
  5440. @"
  5441. *****0*
  5442. ***** *
  5443. *****你
  5444. ***** *
  5445. *****4*
  5446. *******
  5447. *******")]
  5448. [InlineData (
  5449. "0 你 4",
  5450. Alignment.End,
  5451. Alignment.End,
  5452. TextDirection.TopBottom_LeftRight,
  5453. @"
  5454. *******
  5455. *******
  5456. *****0*
  5457. ***** *
  5458. *****你
  5459. ***** *
  5460. *****4*")]
  5461. [InlineData (
  5462. "0 你 4",
  5463. Alignment.End,
  5464. Alignment.Center,
  5465. TextDirection.TopBottom_LeftRight,
  5466. @"
  5467. *******
  5468. *****0*
  5469. ***** *
  5470. *****你
  5471. ***** *
  5472. *****4*
  5473. *******")]
  5474. [InlineData (
  5475. "0 你 4",
  5476. Alignment.End,
  5477. Alignment.Fill,
  5478. TextDirection.TopBottom_LeftRight,
  5479. @"
  5480. *****0*
  5481. ***** *
  5482. ***** *
  5483. *****你
  5484. ***** *
  5485. ***** *
  5486. *****4*")]
  5487. // TopBottom_RightLeft
  5488. [InlineData (
  5489. "0 2 4",
  5490. Alignment.End,
  5491. Alignment.Start,
  5492. TextDirection.TopBottom_RightLeft,
  5493. @"
  5494. ******0
  5495. ******
  5496. ******2
  5497. ******
  5498. ******4
  5499. *******
  5500. *******")]
  5501. [InlineData (
  5502. "0 2 4",
  5503. Alignment.End,
  5504. Alignment.End,
  5505. TextDirection.TopBottom_RightLeft,
  5506. @"
  5507. *******
  5508. *******
  5509. ******0
  5510. ******
  5511. ******2
  5512. ******
  5513. ******4")]
  5514. [InlineData (
  5515. "0 2 4",
  5516. Alignment.End,
  5517. Alignment.Center,
  5518. TextDirection.TopBottom_RightLeft,
  5519. @"
  5520. *******
  5521. ******0
  5522. ******
  5523. ******2
  5524. ******
  5525. ******4
  5526. *******")]
  5527. [InlineData (
  5528. "0 2 4",
  5529. Alignment.End,
  5530. Alignment.Fill,
  5531. TextDirection.TopBottom_RightLeft,
  5532. @"
  5533. ******0
  5534. ******
  5535. ******
  5536. ******2
  5537. ******
  5538. ******
  5539. ******4")]
  5540. [InlineData (
  5541. "0 你 4",
  5542. Alignment.End,
  5543. Alignment.Start,
  5544. TextDirection.TopBottom_RightLeft,
  5545. @"
  5546. *****0*
  5547. ***** *
  5548. *****你
  5549. ***** *
  5550. *****4*
  5551. *******
  5552. *******")]
  5553. [InlineData (
  5554. "0 你 4",
  5555. Alignment.End,
  5556. Alignment.End,
  5557. TextDirection.TopBottom_RightLeft,
  5558. @"
  5559. *******
  5560. *******
  5561. *****0*
  5562. ***** *
  5563. *****你
  5564. ***** *
  5565. *****4*")]
  5566. [InlineData (
  5567. "0 你 4",
  5568. Alignment.End,
  5569. Alignment.Center,
  5570. TextDirection.TopBottom_RightLeft,
  5571. @"
  5572. *******
  5573. *****0*
  5574. ***** *
  5575. *****你
  5576. ***** *
  5577. *****4*
  5578. *******")]
  5579. [InlineData (
  5580. "0 你 4",
  5581. Alignment.End,
  5582. Alignment.Fill,
  5583. TextDirection.TopBottom_RightLeft,
  5584. @"
  5585. *****0*
  5586. ***** *
  5587. ***** *
  5588. *****你
  5589. ***** *
  5590. ***** *
  5591. *****4*")]
  5592. // BottomTop_LeftRight
  5593. [InlineData (
  5594. "0 2 4",
  5595. Alignment.End,
  5596. Alignment.Start,
  5597. TextDirection.BottomTop_LeftRight,
  5598. @"
  5599. ******4
  5600. ******
  5601. ******2
  5602. ******
  5603. ******0
  5604. *******
  5605. *******")]
  5606. [InlineData (
  5607. "0 2 4",
  5608. Alignment.End,
  5609. Alignment.End,
  5610. TextDirection.BottomTop_LeftRight,
  5611. @"
  5612. *******
  5613. *******
  5614. ******4
  5615. ******
  5616. ******2
  5617. ******
  5618. ******0")]
  5619. [InlineData (
  5620. "0 2 4",
  5621. Alignment.End,
  5622. Alignment.Center,
  5623. TextDirection.BottomTop_LeftRight,
  5624. @"
  5625. *******
  5626. ******4
  5627. ******
  5628. ******2
  5629. ******
  5630. ******0
  5631. *******")]
  5632. [InlineData (
  5633. "0 2 4",
  5634. Alignment.End,
  5635. Alignment.Fill,
  5636. TextDirection.BottomTop_LeftRight,
  5637. @"
  5638. ******4
  5639. ******
  5640. ******
  5641. ******2
  5642. ******
  5643. ******
  5644. ******0")]
  5645. [InlineData (
  5646. "0 你 4",
  5647. Alignment.End,
  5648. Alignment.Start,
  5649. TextDirection.BottomTop_LeftRight,
  5650. @"
  5651. *****4*
  5652. ***** *
  5653. *****你
  5654. ***** *
  5655. *****0*
  5656. *******
  5657. *******")]
  5658. [InlineData (
  5659. "0 你 4",
  5660. Alignment.End,
  5661. Alignment.End,
  5662. TextDirection.BottomTop_LeftRight,
  5663. @"
  5664. *******
  5665. *******
  5666. *****4*
  5667. ***** *
  5668. *****你
  5669. ***** *
  5670. *****0*")]
  5671. [InlineData (
  5672. "0 你 4",
  5673. Alignment.End,
  5674. Alignment.Center,
  5675. TextDirection.BottomTop_LeftRight,
  5676. @"
  5677. *******
  5678. *****4*
  5679. ***** *
  5680. *****你
  5681. ***** *
  5682. *****0*
  5683. *******")]
  5684. [InlineData (
  5685. "0 你 4",
  5686. Alignment.End,
  5687. Alignment.Fill,
  5688. TextDirection.BottomTop_LeftRight,
  5689. @"
  5690. *****4*
  5691. ***** *
  5692. ***** *
  5693. *****你
  5694. ***** *
  5695. ***** *
  5696. *****0*")]
  5697. // BottomTop_RightLeft
  5698. [InlineData (
  5699. "0 2 4",
  5700. Alignment.End,
  5701. Alignment.Start,
  5702. TextDirection.BottomTop_RightLeft,
  5703. @"
  5704. ******4
  5705. ******
  5706. ******2
  5707. ******
  5708. ******0
  5709. *******
  5710. *******")]
  5711. [InlineData (
  5712. "0 2 4",
  5713. Alignment.End,
  5714. Alignment.End,
  5715. TextDirection.BottomTop_RightLeft,
  5716. @"
  5717. *******
  5718. *******
  5719. ******4
  5720. ******
  5721. ******2
  5722. ******
  5723. ******0")]
  5724. [InlineData (
  5725. "0 2 4",
  5726. Alignment.End,
  5727. Alignment.Center,
  5728. TextDirection.BottomTop_RightLeft,
  5729. @"
  5730. *******
  5731. ******4
  5732. ******
  5733. ******2
  5734. ******
  5735. ******0
  5736. *******")]
  5737. [InlineData (
  5738. "0 2 4",
  5739. Alignment.End,
  5740. Alignment.Fill,
  5741. TextDirection.BottomTop_RightLeft,
  5742. @"
  5743. ******4
  5744. ******
  5745. ******
  5746. ******2
  5747. ******
  5748. ******
  5749. ******0")]
  5750. [InlineData (
  5751. "0 你 4",
  5752. Alignment.End,
  5753. Alignment.Start,
  5754. TextDirection.BottomTop_RightLeft,
  5755. @"
  5756. *****4*
  5757. ***** *
  5758. *****你
  5759. ***** *
  5760. *****0*
  5761. *******
  5762. *******")]
  5763. [InlineData (
  5764. "0 你 4",
  5765. Alignment.End,
  5766. Alignment.End,
  5767. TextDirection.BottomTop_RightLeft,
  5768. @"
  5769. *******
  5770. *******
  5771. *****4*
  5772. ***** *
  5773. *****你
  5774. ***** *
  5775. *****0*")]
  5776. [InlineData (
  5777. "0 你 4",
  5778. Alignment.End,
  5779. Alignment.Center,
  5780. TextDirection.BottomTop_RightLeft,
  5781. @"
  5782. *******
  5783. *****4*
  5784. ***** *
  5785. *****你
  5786. ***** *
  5787. *****0*
  5788. *******")]
  5789. [InlineData (
  5790. "0 你 4",
  5791. Alignment.End,
  5792. Alignment.Fill,
  5793. TextDirection.BottomTop_RightLeft,
  5794. @"
  5795. *****4*
  5796. ***** *
  5797. ***** *
  5798. *****你
  5799. ***** *
  5800. ***** *
  5801. *****0*")]
  5802. // Vertical with alignment.Centered
  5803. // TopBottom_LeftRight
  5804. [InlineData (
  5805. "0 2 4",
  5806. Alignment.Center,
  5807. Alignment.Start,
  5808. TextDirection.TopBottom_LeftRight,
  5809. @"
  5810. ***0***
  5811. *** ***
  5812. ***2***
  5813. *** ***
  5814. ***4***
  5815. *******
  5816. *******")]
  5817. [InlineData (
  5818. "0 2 4",
  5819. Alignment.Center,
  5820. Alignment.End,
  5821. TextDirection.TopBottom_LeftRight,
  5822. @"
  5823. *******
  5824. *******
  5825. ***0***
  5826. *** ***
  5827. ***2***
  5828. *** ***
  5829. ***4***")]
  5830. [InlineData (
  5831. "0 2 4",
  5832. Alignment.Center,
  5833. Alignment.Center,
  5834. TextDirection.TopBottom_LeftRight,
  5835. @"
  5836. *******
  5837. ***0***
  5838. *** ***
  5839. ***2***
  5840. *** ***
  5841. ***4***
  5842. *******")]
  5843. [InlineData (
  5844. "0 2 4",
  5845. Alignment.Center,
  5846. Alignment.Fill,
  5847. TextDirection.TopBottom_LeftRight,
  5848. @"
  5849. ***0***
  5850. *** ***
  5851. *** ***
  5852. ***2***
  5853. *** ***
  5854. *** ***
  5855. ***4***")]
  5856. [InlineData (
  5857. "0 你 4",
  5858. Alignment.Center,
  5859. Alignment.Start,
  5860. TextDirection.TopBottom_LeftRight,
  5861. @"
  5862. **0****
  5863. ** ****
  5864. **你***
  5865. ** ****
  5866. **4****
  5867. *******
  5868. *******")]
  5869. [InlineData (
  5870. "0 你 4",
  5871. Alignment.Center,
  5872. Alignment.End,
  5873. TextDirection.TopBottom_LeftRight,
  5874. @"
  5875. *******
  5876. *******
  5877. **0****
  5878. ** ****
  5879. **你***
  5880. ** ****
  5881. **4****")]
  5882. [InlineData (
  5883. "0 你 4",
  5884. Alignment.Center,
  5885. Alignment.Center,
  5886. TextDirection.TopBottom_LeftRight,
  5887. @"
  5888. *******
  5889. **0****
  5890. ** ****
  5891. **你***
  5892. ** ****
  5893. **4****
  5894. *******")]
  5895. [InlineData (
  5896. "0 你 4",
  5897. Alignment.Center,
  5898. Alignment.Fill,
  5899. TextDirection.TopBottom_LeftRight,
  5900. @"
  5901. **0****
  5902. ** ****
  5903. ** ****
  5904. **你***
  5905. ** ****
  5906. ** ****
  5907. **4****")]
  5908. // TopBottom_RightLeft
  5909. [InlineData (
  5910. "0 2 4",
  5911. Alignment.Center,
  5912. Alignment.Start,
  5913. TextDirection.TopBottom_RightLeft,
  5914. @"
  5915. ***0***
  5916. *** ***
  5917. ***2***
  5918. *** ***
  5919. ***4***
  5920. *******
  5921. *******")]
  5922. [InlineData (
  5923. "0 2 4",
  5924. Alignment.Center,
  5925. Alignment.End,
  5926. TextDirection.TopBottom_RightLeft,
  5927. @"
  5928. *******
  5929. *******
  5930. ***0***
  5931. *** ***
  5932. ***2***
  5933. *** ***
  5934. ***4***")]
  5935. [InlineData (
  5936. "0 2 4",
  5937. Alignment.Center,
  5938. Alignment.Center,
  5939. TextDirection.TopBottom_RightLeft,
  5940. @"
  5941. *******
  5942. ***0***
  5943. *** ***
  5944. ***2***
  5945. *** ***
  5946. ***4***
  5947. *******")]
  5948. [InlineData (
  5949. "0 2 4",
  5950. Alignment.Center,
  5951. Alignment.Fill,
  5952. TextDirection.TopBottom_RightLeft,
  5953. @"
  5954. ***0***
  5955. *** ***
  5956. *** ***
  5957. ***2***
  5958. *** ***
  5959. *** ***
  5960. ***4***")]
  5961. [InlineData (
  5962. "0 你 4",
  5963. Alignment.Center,
  5964. Alignment.Start,
  5965. TextDirection.TopBottom_RightLeft,
  5966. @"
  5967. **0****
  5968. ** ****
  5969. **你***
  5970. ** ****
  5971. **4****
  5972. *******
  5973. *******")]
  5974. [InlineData (
  5975. "0 你 4",
  5976. Alignment.Center,
  5977. Alignment.End,
  5978. TextDirection.TopBottom_RightLeft,
  5979. @"
  5980. *******
  5981. *******
  5982. **0****
  5983. ** ****
  5984. **你***
  5985. ** ****
  5986. **4****")]
  5987. [InlineData (
  5988. "0 你 4",
  5989. Alignment.Center,
  5990. Alignment.Center,
  5991. TextDirection.TopBottom_RightLeft,
  5992. @"
  5993. *******
  5994. **0****
  5995. ** ****
  5996. **你***
  5997. ** ****
  5998. **4****
  5999. *******")]
  6000. [InlineData (
  6001. "0 你 4",
  6002. Alignment.Center,
  6003. Alignment.Fill,
  6004. TextDirection.TopBottom_RightLeft,
  6005. @"
  6006. **0****
  6007. ** ****
  6008. ** ****
  6009. **你***
  6010. ** ****
  6011. ** ****
  6012. **4****")]
  6013. // BottomTop_LeftRight
  6014. [InlineData (
  6015. "0 2 4",
  6016. Alignment.Center,
  6017. Alignment.Start,
  6018. TextDirection.BottomTop_LeftRight,
  6019. @"
  6020. ***4***
  6021. *** ***
  6022. ***2***
  6023. *** ***
  6024. ***0***
  6025. *******
  6026. *******")]
  6027. [InlineData (
  6028. "0 2 4",
  6029. Alignment.Center,
  6030. Alignment.End,
  6031. TextDirection.BottomTop_LeftRight,
  6032. @"
  6033. *******
  6034. *******
  6035. ***4***
  6036. *** ***
  6037. ***2***
  6038. *** ***
  6039. ***0***")]
  6040. [InlineData (
  6041. "0 2 4",
  6042. Alignment.Center,
  6043. Alignment.Center,
  6044. TextDirection.BottomTop_LeftRight,
  6045. @"
  6046. *******
  6047. ***4***
  6048. *** ***
  6049. ***2***
  6050. *** ***
  6051. ***0***
  6052. *******")]
  6053. [InlineData (
  6054. "0 2 4",
  6055. Alignment.Center,
  6056. Alignment.Fill,
  6057. TextDirection.BottomTop_LeftRight,
  6058. @"
  6059. ***4***
  6060. *** ***
  6061. *** ***
  6062. ***2***
  6063. *** ***
  6064. *** ***
  6065. ***0***")]
  6066. [InlineData (
  6067. "0 你 4",
  6068. Alignment.Center,
  6069. Alignment.Start,
  6070. TextDirection.BottomTop_LeftRight,
  6071. @"
  6072. **4****
  6073. ** ****
  6074. **你***
  6075. ** ****
  6076. **0****
  6077. *******
  6078. *******")]
  6079. [InlineData (
  6080. "0 你 4",
  6081. Alignment.Center,
  6082. Alignment.End,
  6083. TextDirection.BottomTop_LeftRight,
  6084. @"
  6085. *******
  6086. *******
  6087. **4****
  6088. ** ****
  6089. **你***
  6090. ** ****
  6091. **0****")]
  6092. [InlineData (
  6093. "0 你 4",
  6094. Alignment.Center,
  6095. Alignment.Center,
  6096. TextDirection.BottomTop_LeftRight,
  6097. @"
  6098. *******
  6099. **4****
  6100. ** ****
  6101. **你***
  6102. ** ****
  6103. **0****
  6104. *******")]
  6105. [InlineData (
  6106. "0 你 4",
  6107. Alignment.Center,
  6108. Alignment.Fill,
  6109. TextDirection.BottomTop_LeftRight,
  6110. @"
  6111. **4****
  6112. ** ****
  6113. ** ****
  6114. **你***
  6115. ** ****
  6116. ** ****
  6117. **0****")]
  6118. // BottomTop_RightLeft
  6119. [InlineData (
  6120. "0 2 4",
  6121. Alignment.Center,
  6122. Alignment.Start,
  6123. TextDirection.BottomTop_RightLeft,
  6124. @"
  6125. ***4***
  6126. *** ***
  6127. ***2***
  6128. *** ***
  6129. ***0***
  6130. *******
  6131. *******")]
  6132. [InlineData (
  6133. "0 2 4",
  6134. Alignment.Center,
  6135. Alignment.End,
  6136. TextDirection.BottomTop_RightLeft,
  6137. @"
  6138. *******
  6139. *******
  6140. ***4***
  6141. *** ***
  6142. ***2***
  6143. *** ***
  6144. ***0***")]
  6145. [InlineData (
  6146. "0 2 4",
  6147. Alignment.Center,
  6148. Alignment.Center,
  6149. TextDirection.BottomTop_RightLeft,
  6150. @"
  6151. *******
  6152. ***4***
  6153. *** ***
  6154. ***2***
  6155. *** ***
  6156. ***0***
  6157. *******")]
  6158. [InlineData (
  6159. "0 2 4",
  6160. Alignment.Center,
  6161. Alignment.Fill,
  6162. TextDirection.BottomTop_RightLeft,
  6163. @"
  6164. ***4***
  6165. *** ***
  6166. *** ***
  6167. ***2***
  6168. *** ***
  6169. *** ***
  6170. ***0***")]
  6171. [InlineData (
  6172. "0 你 4",
  6173. Alignment.Center,
  6174. Alignment.Start,
  6175. TextDirection.BottomTop_RightLeft,
  6176. @"
  6177. **4****
  6178. ** ****
  6179. **你***
  6180. ** ****
  6181. **0****
  6182. *******
  6183. *******")]
  6184. [InlineData (
  6185. "0 你 4",
  6186. Alignment.Center,
  6187. Alignment.End,
  6188. TextDirection.BottomTop_RightLeft,
  6189. @"
  6190. *******
  6191. *******
  6192. **4****
  6193. ** ****
  6194. **你***
  6195. ** ****
  6196. **0****")]
  6197. [InlineData (
  6198. "0 你 4",
  6199. Alignment.Center,
  6200. Alignment.Center,
  6201. TextDirection.BottomTop_RightLeft,
  6202. @"
  6203. *******
  6204. **4****
  6205. ** ****
  6206. **你***
  6207. ** ****
  6208. **0****
  6209. *******")]
  6210. [InlineData (
  6211. "0 你 4",
  6212. Alignment.Center,
  6213. Alignment.Fill,
  6214. TextDirection.BottomTop_RightLeft,
  6215. @"
  6216. **4****
  6217. ** ****
  6218. ** ****
  6219. **你***
  6220. ** ****
  6221. ** ****
  6222. **0****")]
  6223. // Vertical with alignment.Justified
  6224. // TopBottom_LeftRight
  6225. [InlineData (
  6226. "0 2 4",
  6227. Alignment.Fill,
  6228. Alignment.Start,
  6229. TextDirection.TopBottom_LeftRight,
  6230. @"
  6231. 0******
  6232. ******
  6233. 2******
  6234. ******
  6235. 4******
  6236. *******
  6237. *******")]
  6238. [InlineData (
  6239. "0 2 4",
  6240. Alignment.Fill,
  6241. Alignment.End,
  6242. TextDirection.TopBottom_LeftRight,
  6243. @"
  6244. *******
  6245. *******
  6246. 0******
  6247. ******
  6248. 2******
  6249. ******
  6250. 4******")]
  6251. [InlineData (
  6252. "0 2 4",
  6253. Alignment.Fill,
  6254. Alignment.Center,
  6255. TextDirection.TopBottom_LeftRight,
  6256. @"
  6257. *******
  6258. 0******
  6259. ******
  6260. 2******
  6261. ******
  6262. 4******
  6263. *******")]
  6264. [InlineData (
  6265. "0 2 4",
  6266. Alignment.Fill,
  6267. Alignment.Fill,
  6268. TextDirection.TopBottom_LeftRight,
  6269. @"
  6270. 0******
  6271. ******
  6272. ******
  6273. 2******
  6274. ******
  6275. ******
  6276. 4******")]
  6277. [InlineData (
  6278. "0 你 4",
  6279. Alignment.Fill,
  6280. Alignment.Start,
  6281. TextDirection.TopBottom_LeftRight,
  6282. @"
  6283. 0******
  6284. ******
  6285. 你*****
  6286. ******
  6287. 4******
  6288. *******
  6289. *******")]
  6290. [InlineData (
  6291. "0 你 4",
  6292. Alignment.Fill,
  6293. Alignment.End,
  6294. TextDirection.TopBottom_LeftRight,
  6295. @"
  6296. *******
  6297. *******
  6298. 0******
  6299. ******
  6300. 你*****
  6301. ******
  6302. 4******")]
  6303. [InlineData (
  6304. "0 你 4",
  6305. Alignment.Fill,
  6306. Alignment.Center,
  6307. TextDirection.TopBottom_LeftRight,
  6308. @"
  6309. *******
  6310. 0******
  6311. ******
  6312. 你*****
  6313. ******
  6314. 4******
  6315. *******")]
  6316. [InlineData (
  6317. "0 你 4",
  6318. Alignment.Fill,
  6319. Alignment.Fill,
  6320. TextDirection.TopBottom_LeftRight,
  6321. @"
  6322. 0******
  6323. ******
  6324. ******
  6325. 你*****
  6326. ******
  6327. ******
  6328. 4******")]
  6329. // TopBottom_RightLeft
  6330. [InlineData (
  6331. "0 2 4",
  6332. Alignment.Fill,
  6333. Alignment.Start,
  6334. TextDirection.TopBottom_RightLeft,
  6335. @"
  6336. 0******
  6337. ******
  6338. 2******
  6339. ******
  6340. 4******
  6341. *******
  6342. *******")]
  6343. [InlineData (
  6344. "0 2 4",
  6345. Alignment.Fill,
  6346. Alignment.End,
  6347. TextDirection.TopBottom_RightLeft,
  6348. @"
  6349. *******
  6350. *******
  6351. 0******
  6352. ******
  6353. 2******
  6354. ******
  6355. 4******")]
  6356. [InlineData (
  6357. "0 2 4",
  6358. Alignment.Fill,
  6359. Alignment.Center,
  6360. TextDirection.TopBottom_RightLeft,
  6361. @"
  6362. *******
  6363. 0******
  6364. ******
  6365. 2******
  6366. ******
  6367. 4******
  6368. *******")]
  6369. [InlineData (
  6370. "0 2 4",
  6371. Alignment.Fill,
  6372. Alignment.Fill,
  6373. TextDirection.TopBottom_RightLeft,
  6374. @"
  6375. 0******
  6376. ******
  6377. ******
  6378. 2******
  6379. ******
  6380. ******
  6381. 4******")]
  6382. [InlineData (
  6383. "0 你 4",
  6384. Alignment.Fill,
  6385. Alignment.Start,
  6386. TextDirection.TopBottom_RightLeft,
  6387. @"
  6388. 0******
  6389. ******
  6390. 你*****
  6391. ******
  6392. 4******
  6393. *******
  6394. *******")]
  6395. [InlineData (
  6396. "0 你 4",
  6397. Alignment.Fill,
  6398. Alignment.End,
  6399. TextDirection.TopBottom_RightLeft,
  6400. @"
  6401. *******
  6402. *******
  6403. 0******
  6404. ******
  6405. 你*****
  6406. ******
  6407. 4******")]
  6408. [InlineData (
  6409. "0 你 4",
  6410. Alignment.Fill,
  6411. Alignment.Center,
  6412. TextDirection.TopBottom_RightLeft,
  6413. @"
  6414. *******
  6415. 0******
  6416. ******
  6417. 你*****
  6418. ******
  6419. 4******
  6420. *******")]
  6421. [InlineData (
  6422. "0 你 4",
  6423. Alignment.Fill,
  6424. Alignment.Fill,
  6425. TextDirection.TopBottom_RightLeft,
  6426. @"
  6427. 0******
  6428. ******
  6429. ******
  6430. 你*****
  6431. ******
  6432. ******
  6433. 4******")]
  6434. // BottomTop_LeftRight
  6435. [InlineData (
  6436. "0 2 4",
  6437. Alignment.Fill,
  6438. Alignment.Start,
  6439. TextDirection.BottomTop_LeftRight,
  6440. @"
  6441. 4******
  6442. ******
  6443. 2******
  6444. ******
  6445. 0******
  6446. *******
  6447. *******")]
  6448. [InlineData (
  6449. "0 2 4",
  6450. Alignment.Fill,
  6451. Alignment.End,
  6452. TextDirection.BottomTop_LeftRight,
  6453. @"
  6454. *******
  6455. *******
  6456. 4******
  6457. ******
  6458. 2******
  6459. ******
  6460. 0******")]
  6461. [InlineData (
  6462. "0 2 4",
  6463. Alignment.Fill,
  6464. Alignment.Center,
  6465. TextDirection.BottomTop_LeftRight,
  6466. @"
  6467. *******
  6468. 4******
  6469. ******
  6470. 2******
  6471. ******
  6472. 0******
  6473. *******")]
  6474. [InlineData (
  6475. "0 2 4",
  6476. Alignment.Fill,
  6477. Alignment.Fill,
  6478. TextDirection.BottomTop_LeftRight,
  6479. @"
  6480. 4******
  6481. ******
  6482. ******
  6483. 2******
  6484. ******
  6485. ******
  6486. 0******")]
  6487. [InlineData (
  6488. "0 你 4",
  6489. Alignment.Fill,
  6490. Alignment.Start,
  6491. TextDirection.BottomTop_LeftRight,
  6492. @"
  6493. 4******
  6494. ******
  6495. 你*****
  6496. ******
  6497. 0******
  6498. *******
  6499. *******")]
  6500. [InlineData (
  6501. "0 你 4",
  6502. Alignment.Fill,
  6503. Alignment.End,
  6504. TextDirection.BottomTop_LeftRight,
  6505. @"
  6506. *******
  6507. *******
  6508. 4******
  6509. ******
  6510. 你*****
  6511. ******
  6512. 0******")]
  6513. [InlineData (
  6514. "0 你 4",
  6515. Alignment.Fill,
  6516. Alignment.Center,
  6517. TextDirection.BottomTop_LeftRight,
  6518. @"
  6519. *******
  6520. 4******
  6521. ******
  6522. 你*****
  6523. ******
  6524. 0******
  6525. *******")]
  6526. [InlineData (
  6527. "0 你 4",
  6528. Alignment.Fill,
  6529. Alignment.Fill,
  6530. TextDirection.BottomTop_LeftRight,
  6531. @"
  6532. 4******
  6533. ******
  6534. ******
  6535. 你*****
  6536. ******
  6537. ******
  6538. 0******")]
  6539. // BottomTop_RightLeft
  6540. [InlineData (
  6541. "0 2 4",
  6542. Alignment.Fill,
  6543. Alignment.Start,
  6544. TextDirection.BottomTop_RightLeft,
  6545. @"
  6546. 4******
  6547. ******
  6548. 2******
  6549. ******
  6550. 0******
  6551. *******
  6552. *******")]
  6553. [InlineData (
  6554. "0 2 4",
  6555. Alignment.Fill,
  6556. Alignment.End,
  6557. TextDirection.BottomTop_RightLeft,
  6558. @"
  6559. *******
  6560. *******
  6561. 4******
  6562. ******
  6563. 2******
  6564. ******
  6565. 0******")]
  6566. [InlineData (
  6567. "0 2 4",
  6568. Alignment.Fill,
  6569. Alignment.Center,
  6570. TextDirection.BottomTop_RightLeft,
  6571. @"
  6572. *******
  6573. 4******
  6574. ******
  6575. 2******
  6576. ******
  6577. 0******
  6578. *******")]
  6579. [InlineData (
  6580. "0 2 4",
  6581. Alignment.Fill,
  6582. Alignment.Fill,
  6583. TextDirection.BottomTop_RightLeft,
  6584. @"
  6585. 4******
  6586. ******
  6587. ******
  6588. 2******
  6589. ******
  6590. ******
  6591. 0******")]
  6592. [InlineData (
  6593. "0 你 4",
  6594. Alignment.Fill,
  6595. Alignment.Start,
  6596. TextDirection.BottomTop_RightLeft,
  6597. @"
  6598. 4******
  6599. ******
  6600. 你*****
  6601. ******
  6602. 0******
  6603. *******
  6604. *******")]
  6605. [InlineData (
  6606. "0 你 4",
  6607. Alignment.Fill,
  6608. Alignment.End,
  6609. TextDirection.BottomTop_RightLeft,
  6610. @"
  6611. *******
  6612. *******
  6613. 4******
  6614. ******
  6615. 你*****
  6616. ******
  6617. 0******")]
  6618. [InlineData (
  6619. "0 你 4",
  6620. Alignment.Fill,
  6621. Alignment.Center,
  6622. TextDirection.BottomTop_RightLeft,
  6623. @"
  6624. *******
  6625. 4******
  6626. ******
  6627. 你*****
  6628. ******
  6629. 0******
  6630. *******")]
  6631. [InlineData (
  6632. "0 你 4",
  6633. Alignment.Fill,
  6634. Alignment.Fill,
  6635. TextDirection.BottomTop_RightLeft,
  6636. @"
  6637. 4******
  6638. ******
  6639. ******
  6640. 你*****
  6641. ******
  6642. ******
  6643. 0******")]
  6644. public void Draw_Text_Justification (string text, Alignment horizontalTextAlignment, Alignment alignment, TextDirection textDirection, string expectedText)
  6645. {
  6646. TextFormatter tf = new ()
  6647. {
  6648. Alignment = horizontalTextAlignment,
  6649. VerticalAlignment = alignment,
  6650. Direction = textDirection,
  6651. ConstrainToSize = new (7, 7),
  6652. Text = text
  6653. };
  6654. Application.Driver.FillRect (new (0, 0, 7, 7), (Rune)'*');
  6655. tf.Draw (new (0, 0, 7, 7), Attribute.Default, Attribute.Default);
  6656. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  6657. }
  6658. // Test that changing TextFormatter does not impact View dimensions if Dim.Auto is not in play
  6659. [Fact]
  6660. public void Not_Used_TextFormatter_Does_Not_Change_View_Size ()
  6661. {
  6662. View view = new ()
  6663. {
  6664. Text = "_1234"
  6665. };
  6666. Assert.Equal (Size.Empty, view.Frame.Size);
  6667. view.TextFormatter.Text = "ABC";
  6668. Assert.Equal (Size.Empty, view.Frame.Size);
  6669. view.TextFormatter.Alignment = Alignment.Fill;
  6670. Assert.Equal (Size.Empty, view.Frame.Size);
  6671. view.TextFormatter.VerticalAlignment = Alignment.Center;
  6672. Assert.Equal (Size.Empty, view.Frame.Size);
  6673. view.TextFormatter.HotKeySpecifier = (Rune)'*';
  6674. Assert.Equal (Size.Empty, view.Frame.Size);
  6675. view.TextFormatter.Text = "*ABC";
  6676. Assert.Equal (Size.Empty, view.Frame.Size);
  6677. }
  6678. [Fact]
  6679. public void Not_Used_TextSettings_Do_Not_Change_View_Size ()
  6680. {
  6681. View view = new ()
  6682. {
  6683. Text = "_1234"
  6684. };
  6685. Assert.Equal (Size.Empty, view.Frame.Size);
  6686. view.TextAlignment = Alignment.Fill;
  6687. Assert.Equal (Size.Empty, view.Frame.Size);
  6688. view.VerticalTextAlignment = Alignment.Center;
  6689. Assert.Equal (Size.Empty, view.Frame.Size);
  6690. view.HotKeySpecifier = (Rune)'*';
  6691. Assert.Equal (Size.Empty, view.Frame.Size);
  6692. view.Text = "*ABC";
  6693. Assert.Equal (Size.Empty, view.Frame.Size);
  6694. }
  6695. #region FormatAndGetSizeTests
  6696. // TODO: Add multi-line examples
  6697. // TODO: Add other TextDirection examples
  6698. [Theory]
  6699. [SetupFakeDriver]
  6700. [InlineData ("界1234", 10, 10, TextDirection.LeftRight_TopBottom, 6, 1, @"界1234")]
  6701. [InlineData ("01234", 10, 10, TextDirection.LeftRight_TopBottom, 5, 1, @"01234")]
  6702. [InlineData (
  6703. "界1234",
  6704. 10,
  6705. 10,
  6706. TextDirection.TopBottom_LeftRight,
  6707. 2,
  6708. 5,
  6709. """
  6710. 1
  6711. 2
  6712. 3
  6713. 4
  6714. """)]
  6715. [InlineData (
  6716. "01234",
  6717. 10,
  6718. 10,
  6719. TextDirection.TopBottom_LeftRight,
  6720. 1,
  6721. 5,
  6722. """
  6723. 0
  6724. 1
  6725. 2
  6726. 3
  6727. 4
  6728. """)]
  6729. [InlineData (
  6730. "界1234",
  6731. 3,
  6732. 3,
  6733. TextDirection.LeftRight_TopBottom,
  6734. 3,
  6735. 2,
  6736. """
  6737. 界1
  6738. 234
  6739. """)]
  6740. [InlineData (
  6741. "01234",
  6742. 3,
  6743. 3,
  6744. TextDirection.LeftRight_TopBottom,
  6745. 3,
  6746. 2,
  6747. """
  6748. 012
  6749. 34
  6750. """)]
  6751. [InlineData (
  6752. "界1234",
  6753. 3,
  6754. 3,
  6755. TextDirection.TopBottom_LeftRight,
  6756. 3,
  6757. 3,
  6758. """
  6759. 界3
  6760. 1 4
  6761. 2
  6762. """)]
  6763. [InlineData (
  6764. "01234",
  6765. 3,
  6766. 3,
  6767. TextDirection.TopBottom_LeftRight,
  6768. 2,
  6769. 3,
  6770. """
  6771. 03
  6772. 14
  6773. 2
  6774. """)]
  6775. [InlineData ("01234", 2, 1, TextDirection.LeftRight_TopBottom, 2, 1, @"01")]
  6776. public void FormatAndGetSize_Returns_Correct_Size (
  6777. string text,
  6778. int width,
  6779. int height,
  6780. TextDirection direction,
  6781. int expectedWidth,
  6782. int expectedHeight,
  6783. string expectedDraw
  6784. )
  6785. {
  6786. TextFormatter tf = new ()
  6787. {
  6788. Direction = direction,
  6789. ConstrainToWidth = width,
  6790. ConstrainToHeight = height,
  6791. Text = text
  6792. };
  6793. Assert.True (tf.WordWrap);
  6794. Size size = tf.FormatAndGetSize ();
  6795. Assert.Equal (new (expectedWidth, expectedHeight), size);
  6796. tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default);
  6797. TestHelpers.AssertDriverContentsWithFrameAre (expectedDraw, _output);
  6798. }
  6799. [Theory]
  6800. [SetupFakeDriver]
  6801. [InlineData ("界1234", 10, 10, TextDirection.LeftRight_TopBottom, 6, 1, @"界1234")]
  6802. [InlineData ("01234", 10, 10, TextDirection.LeftRight_TopBottom, 5, 1, @"01234")]
  6803. [InlineData (
  6804. "界1234",
  6805. 10,
  6806. 10,
  6807. TextDirection.TopBottom_LeftRight,
  6808. 2,
  6809. 5,
  6810. """
  6811. 1
  6812. 2
  6813. 3
  6814. 4
  6815. """)]
  6816. [InlineData (
  6817. "01234",
  6818. 10,
  6819. 10,
  6820. TextDirection.TopBottom_LeftRight,
  6821. 1,
  6822. 5,
  6823. """
  6824. 0
  6825. 1
  6826. 2
  6827. 3
  6828. 4
  6829. """)]
  6830. [InlineData ("界1234", 3, 3, TextDirection.LeftRight_TopBottom, 3, 1, @"界1")]
  6831. [InlineData ("01234", 3, 3, TextDirection.LeftRight_TopBottom, 3, 1, @"012")]
  6832. [InlineData (
  6833. "界1234",
  6834. 3,
  6835. 3,
  6836. TextDirection.TopBottom_LeftRight,
  6837. 2,
  6838. 3,
  6839. """
  6840. 1
  6841. 2
  6842. """)]
  6843. [InlineData (
  6844. "01234",
  6845. 3,
  6846. 3,
  6847. TextDirection.TopBottom_LeftRight,
  6848. 1,
  6849. 3,
  6850. """
  6851. 0
  6852. 1
  6853. 2
  6854. """)]
  6855. public void FormatAndGetSize_WordWrap_False_Returns_Correct_Size (
  6856. string text,
  6857. int width,
  6858. int height,
  6859. TextDirection direction,
  6860. int expectedWidth,
  6861. int expectedHeight,
  6862. string expectedDraw
  6863. )
  6864. {
  6865. TextFormatter tf = new ()
  6866. {
  6867. Direction = direction,
  6868. ConstrainToSize = new (width, height),
  6869. Text = text,
  6870. WordWrap = false
  6871. };
  6872. Assert.False (tf.WordWrap);
  6873. Size size = tf.FormatAndGetSize ();
  6874. Assert.Equal (new (expectedWidth, expectedHeight), size);
  6875. tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default);
  6876. TestHelpers.AssertDriverContentsWithFrameAre (expectedDraw, _output);
  6877. }
  6878. #endregion
  6879. }