12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178 |
- // Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
- // Use of this source code is governed by a MIT license found in the LICENSE file.
- package codec
- // TODO:
- //
- // We get wrong file/line numbers for calls to test(Marshal|Unmarshal|DeepEqual)Err helper functions.
- // This is solved by t.Helper function, but this only exists from go1.9+.
- //
- // For now, we don't include t.Helper, so the tests can be run (without a suite)
- // in go 1.4+
- import (
- "bufio"
- "bytes"
- "encoding/gob"
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "math"
- "math/rand"
- "net"
- "net/rpc"
- "os"
- "os/exec"
- "path/filepath"
- "reflect"
- "runtime"
- "strconv"
- "strings"
- "sync/atomic"
- "testing"
- "time"
- )
- func init() {
- testPreInitFns = append(testPreInitFns, testInit)
- // fmt.Printf("sizeof: Decoder: %v, Encoder: %v, fauxUnion: %v\n",
- // reflect.TypeOf((*Decoder)(nil)).Elem().Size(),
- // reflect.TypeOf((*Encoder)(nil)).Elem().Size(),
- // reflect.TypeOf((*fauxUnion)(nil)).Elem().Size(),
- // )
- }
- type testCustomStringT string
- // make this a mapbyslice
- type testMbsT []interface{}
- func (testMbsT) MapBySlice() {}
- type testMbsCustStrT []testCustomStringT
- func (testMbsCustStrT) MapBySlice() {}
- // type testSelferRecur struct{}
- // func (s *testSelferRecur) CodecEncodeSelf(e *Encoder) {
- // e.MustEncode(s)
- // }
- // func (s *testSelferRecur) CodecDecodeSelf(d *Decoder) {
- // d.MustDecode(s)
- // }
- type testIntfMapI interface {
- GetIntfMapV() string
- }
- type testIntfMapT1 struct {
- IntfMapV string
- }
- func (x *testIntfMapT1) GetIntfMapV() string { return x.IntfMapV }
- type testIntfMapT2 struct {
- IntfMapV string
- }
- func (x testIntfMapT2) GetIntfMapV() string { return x.IntfMapV }
- var testErrWriterErr = errors.New("testErrWriterErr")
- type testErrWriter struct{}
- func (x *testErrWriter) Write(p []byte) (int, error) {
- return 0, testErrWriterErr
- }
- // ----
- type testVerifyFlag uint8
- const (
- _ testVerifyFlag = 1 << iota
- testVerifyMapTypeSame
- testVerifyMapTypeStrIntf
- testVerifyMapTypeIntfIntf
- // testVerifySliceIntf
- testVerifyForPython
- testVerifyDoNil
- testVerifyTimeAsInteger
- )
- func (f testVerifyFlag) isset(v testVerifyFlag) bool {
- return f&v == v
- }
- // const testSkipRPCTests = false
- var (
- testTableNumPrimitives int
- testTableIdxTime int
- testTableNumMaps int
- // set this when running using bufio, etc
- testSkipRPCTests = false
- )
- var (
- skipVerifyVal interface{} = &(struct{}{})
- testMapStrIntfTyp = reflect.TypeOf(map[string]interface{}(nil))
- // For Go Time, do not use a descriptive timezone.
- // It's unnecessary, and makes it harder to do a reflect.DeepEqual.
- // The Offset already tells what the offset should be, if not on UTC and unknown zone name.
- timeLoc = time.FixedZone("", -8*60*60) // UTC-08:00 //time.UTC-8
- timeToCompare1 = time.Date(2012, 2, 2, 2, 2, 2, 2000, timeLoc).UTC()
- timeToCompare2 = time.Date(1900, 2, 2, 2, 2, 2, 2000, timeLoc).UTC()
- timeToCompare3 = time.Unix(0, 270).UTC() // use value that must be encoded as uint64 for nanoseconds (for cbor/msgpack comparison)
- //timeToCompare4 = time.Time{}.UTC() // does not work well with simple cbor time encoding (overflow)
- timeToCompare4 = time.Unix(-2013855848, 4223).UTC()
- table []interface{} // main items we encode
- // will encode a float32 as float64, or large int as uint
- testRpcInt = new(TestRpcInt)
- )
- var wrapInt64Typ = reflect.TypeOf(wrapInt64(0))
- var wrapBytesTyp = reflect.TypeOf(wrapBytes(nil))
- var testSelfExtTyp = reflect.TypeOf((*TestSelfExtImpl)(nil)).Elem()
- var testSelfExt2Typ = reflect.TypeOf((*TestSelfExtImpl2)(nil)).Elem()
- func testByteBuf(in []byte) *bytes.Buffer {
- return bytes.NewBuffer(in)
- }
- type TestABC struct {
- A, B, C string
- }
- func (x *TestABC) MarshalBinary() ([]byte, error) {
- return []byte(fmt.Sprintf("%s %s %s", x.A, x.B, x.C)), nil
- }
- func (x *TestABC) MarshalText() ([]byte, error) {
- return []byte(fmt.Sprintf("%s %s %s", x.A, x.B, x.C)), nil
- }
- func (x *TestABC) MarshalJSON() ([]byte, error) {
- return []byte(fmt.Sprintf(`"%s %s %s"`, x.A, x.B, x.C)), nil
- }
- func (x *TestABC) UnmarshalBinary(data []byte) (err error) {
- ss := strings.Split(string(data), " ")
- x.A, x.B, x.C = ss[0], ss[1], ss[2]
- return
- }
- func (x *TestABC) UnmarshalText(data []byte) (err error) {
- return x.UnmarshalBinary(data)
- }
- func (x *TestABC) UnmarshalJSON(data []byte) (err error) {
- return x.UnmarshalBinary(data[1 : len(data)-1])
- }
- type TestABC2 struct {
- A, B, C string
- }
- func (x TestABC2) MarshalText() ([]byte, error) {
- return []byte(fmt.Sprintf("%s %s %s", x.A, x.B, x.C)), nil
- }
- func (x *TestABC2) UnmarshalText(data []byte) (err error) {
- ss := strings.Split(string(data), " ")
- x.A, x.B, x.C = ss[0], ss[1], ss[2]
- return
- // _, err = fmt.Sscanf(string(data), "%s %s %s", &x.A, &x.B, &x.C)
- }
- type TestSimplish struct {
- Ii int
- Ss string
- Ar [2]*TestSimplish
- Sl []*TestSimplish
- Mm map[string]*TestSimplish
- }
- type TestRpcABC struct {
- A, B, C string
- }
- type TestRpcInt struct {
- i int
- }
- func (r *TestRpcInt) Update(n int, res *int) error { r.i = n; *res = r.i; return nil }
- func (r *TestRpcInt) Square(ignore int, res *int) error { *res = r.i * r.i; return nil }
- func (r *TestRpcInt) Mult(n int, res *int) error { *res = r.i * n; return nil }
- func (r *TestRpcInt) EchoStruct(arg TestRpcABC, res *string) error {
- *res = fmt.Sprintf("%#v", arg)
- return nil
- }
- func (r *TestRpcInt) Echo123(args []string, res *string) error {
- *res = fmt.Sprintf("%#v", args)
- return nil
- }
- type TestRawValue struct {
- R Raw
- I int
- }
- // ----
- type testUnixNanoTimeExt struct {
- // keep timestamp here, so that do not incur interface-conversion costs
- // ts int64
- }
- func (x *testUnixNanoTimeExt) WriteExt(v interface{}) []byte {
- v2 := v.(*time.Time)
- bs := make([]byte, 8)
- bigen.PutUint64(bs, uint64(v2.UnixNano()))
- return bs
- }
- func (x *testUnixNanoTimeExt) ReadExt(v interface{}, bs []byte) {
- v2 := v.(*time.Time)
- ui := bigen.Uint64(bs)
- *v2 = time.Unix(0, int64(ui)).UTC()
- }
- func (x *testUnixNanoTimeExt) ConvertExt(v interface{}) interface{} {
- v2 := v.(*time.Time) // structs are encoded by passing the ptr
- return v2.UTC().UnixNano()
- }
- func (x *testUnixNanoTimeExt) UpdateExt(dest interface{}, v interface{}) {
- // xdebugf("testUnixNanoTimeExt: v: %#v", v)
- tt := dest.(*time.Time)
- *tt = time.Unix(0, v.(int64)).UTC()
- // switch v2 := v.(type) {
- // case int64:
- // *tt = time.Unix(0, v2).UTC()
- // case uint64:
- // *tt = time.Unix(0, int64(v2)).UTC()
- // //case float64:
- // //case string:
- // default:
- // panic(fmt.Sprintf("unsupported format for time conversion: expecting int64/uint64; got %T", v))
- // }
- }
- // ----
- type wrapInt64Ext int64
- func (x *wrapInt64Ext) WriteExt(v interface{}) []byte {
- v2 := uint64(int64(v.(wrapInt64)))
- bs := make([]byte, 8)
- bigen.PutUint64(bs, v2)
- return bs
- }
- func (x *wrapInt64Ext) ReadExt(v interface{}, bs []byte) {
- v2 := v.(*wrapInt64)
- ui := bigen.Uint64(bs)
- *v2 = wrapInt64(int64(ui))
- }
- func (x *wrapInt64Ext) ConvertExt(v interface{}) interface{} {
- return int64(v.(wrapInt64))
- }
- func (x *wrapInt64Ext) UpdateExt(dest interface{}, v interface{}) {
- v2 := dest.(*wrapInt64)
- *v2 = wrapInt64(v.(int64))
- }
- // ----
- type wrapBytesExt struct{}
- func (x *wrapBytesExt) WriteExt(v interface{}) []byte {
- return ([]byte)(v.(wrapBytes))
- }
- func (x *wrapBytesExt) ReadExt(v interface{}, bs []byte) {
- v2 := v.(*wrapBytes)
- *v2 = wrapBytes(bs)
- }
- func (x *wrapBytesExt) ConvertExt(v interface{}) interface{} {
- return ([]byte)(v.(wrapBytes))
- }
- func (x *wrapBytesExt) UpdateExt(dest interface{}, v interface{}) {
- v2 := dest.(*wrapBytes)
- // some formats (e.g. json) cannot nakedly determine []byte from string, so expect both
- switch v3 := v.(type) {
- case []byte:
- *v2 = wrapBytes(v3)
- case string:
- *v2 = wrapBytes([]byte(v3))
- default:
- panic("UpdateExt for wrapBytesExt expects string or []byte")
- }
- // *v2 = wrapBytes(v.([]byte))
- }
- // ----
- // timeExt is an extension handler for time.Time, that uses binc model for encoding/decoding time.
- // we used binc model, as that is the only custom time representation that we designed ourselves.
- type timeExt struct{}
- func (x timeExt) WriteExt(v interface{}) (bs []byte) {
- switch v2 := v.(type) {
- case time.Time:
- bs = bincEncodeTime(v2)
- case *time.Time:
- bs = bincEncodeTime(*v2)
- default:
- panic(fmt.Errorf("unsupported format for time conversion: expecting time.Time; got %T", v2))
- }
- return
- }
- func (x timeExt) ReadExt(v interface{}, bs []byte) {
- tt, err := bincDecodeTime(bs)
- if err != nil {
- panic(err)
- }
- *(v.(*time.Time)) = tt
- }
- func (x timeExt) ConvertExt(v interface{}) interface{} {
- return x.WriteExt(v)
- }
- func (x timeExt) UpdateExt(v interface{}, src interface{}) {
- x.ReadExt(v, src.([]byte))
- }
- // ----
- func testCodecEncode(ts interface{}, bsIn []byte,
- fn func([]byte) *bytes.Buffer, h Handle) (bs []byte, err error) {
- return sTestCodecEncode(ts, bsIn, fn, h, basicHandle(h))
- }
- func testCodecDecode(bs []byte, ts interface{}, h Handle) (err error) {
- return sTestCodecDecode(bs, ts, h, basicHandle(h))
- }
- func checkErrT(t *testing.T, err error) {
- if err != nil {
- t.Logf(err.Error())
- t.FailNow()
- }
- }
- func checkEqualT(t *testing.T, v1 interface{}, v2 interface{}, desc string) {
- if err := deepEqual(v1, v2); err != nil {
- t.Logf("Not Equal: %s: %v. v1: %v, v2: %v", desc, err, v1, v2)
- t.FailNow()
- }
- }
- func testInit() {
- gob.Register(new(TestStrucFlex))
- if testInitDebug { // TODO: fix testInit to be done on demand, and uncomment below
- // ts0 := newTestStrucFlex(2, testNumRepeatString, false, !testSkipIntf, testMapStringKeyOnly)
- // logTv(nil, "====> depth: %v, ts: %#v\n", 2, ts0)
- }
- for _, v := range testHandles {
- bh := basicHandle(v)
- // pre-fill them first
- bh.EncodeOptions = testEncodeOptions
- bh.DecodeOptions = testDecodeOptions
- // bh.InterfaceReset = true
- // bh.PreferArrayOverSlice = true
- // modify from flag'ish things
- bh.MaxInitLen = testMaxInitLen
- }
- testMsgpackH.WriteExt = true
- var tTimeExt timeExt
- var tBytesExt wrapBytesExt
- var tI64Ext wrapInt64Ext
- // create legacy functions suitable for deprecated AddExt functionality,
- // and use on some places for testSimpleH e.g. for time.Time and wrapInt64
- var (
- myExtEncFn = func(x BytesExt, rv reflect.Value) (bs []byte, err error) {
- defer panicToErr(errDecoratorDef{}, &err)
- bs = x.WriteExt(rv.Interface())
- return
- }
- myExtDecFn = func(x BytesExt, rv reflect.Value, bs []byte) (err error) {
- defer panicToErr(errDecoratorDef{}, &err)
- x.ReadExt(rv.Interface(), bs)
- return
- }
- timeExtEncFn = func(rv reflect.Value) (bs []byte, err error) { return myExtEncFn(tTimeExt, rv) }
- timeExtDecFn = func(rv reflect.Value, bs []byte) (err error) { return myExtDecFn(tTimeExt, rv, bs) }
- wrapInt64ExtEncFn = func(rv reflect.Value) (bs []byte, err error) { return myExtEncFn(&tI64Ext, rv) }
- wrapInt64ExtDecFn = func(rv reflect.Value, bs []byte) (err error) { return myExtDecFn(&tI64Ext, rv, bs) }
- )
- chkErr := func(err error) {
- if err != nil {
- panic(err)
- }
- }
- // time.Time is a native type, so extensions will have no effect.
- // However, we add these here to ensure nothing happens.
- chkErr(testSimpleH.AddExt(timeTyp, 1, timeExtEncFn, timeExtDecFn))
- // testBincH.SetBytesExt(timeTyp, 1, timeExt{}) // time is builtin for binc
- chkErr(testMsgpackH.SetBytesExt(timeTyp, 1, timeExt{}))
- chkErr(testCborH.SetInterfaceExt(timeTyp, 1, &testUnixNanoTimeExt{}))
- // testJsonH.SetInterfaceExt(timeTyp, 1, &testUnixNanoTimeExt{})
- // Add extensions for the testSelfExt
- chkErr(testSimpleH.SetBytesExt(testSelfExtTyp, 78, SelfExt))
- chkErr(testMsgpackH.SetBytesExt(testSelfExtTyp, 78, SelfExt))
- chkErr(testBincH.SetBytesExt(testSelfExtTyp, 78, SelfExt))
- chkErr(testJsonH.SetInterfaceExt(testSelfExtTyp, 78, SelfExt))
- chkErr(testCborH.SetInterfaceExt(testSelfExtTyp, 78, SelfExt))
- chkErr(testSimpleH.SetBytesExt(testSelfExt2Typ, 79, SelfExt))
- chkErr(testMsgpackH.SetBytesExt(testSelfExt2Typ, 79, SelfExt))
- chkErr(testBincH.SetBytesExt(testSelfExt2Typ, 79, SelfExt))
- chkErr(testJsonH.SetInterfaceExt(testSelfExt2Typ, 79, SelfExt))
- chkErr(testCborH.SetInterfaceExt(testSelfExt2Typ, 79, SelfExt))
- // Now, add extensions for the type wrapInt64 and wrapBytes,
- // so we can execute the Encode/Decode Ext paths.
- chkErr(testSimpleH.SetBytesExt(wrapBytesTyp, 32, &tBytesExt))
- chkErr(testMsgpackH.SetBytesExt(wrapBytesTyp, 32, &tBytesExt))
- chkErr(testBincH.SetBytesExt(wrapBytesTyp, 32, &tBytesExt))
- chkErr(testJsonH.SetInterfaceExt(wrapBytesTyp, 32, &tBytesExt))
- chkErr(testCborH.SetInterfaceExt(wrapBytesTyp, 32, &tBytesExt))
- chkErr(testSimpleH.AddExt(wrapInt64Typ, 16, wrapInt64ExtEncFn, wrapInt64ExtDecFn))
- // chkErr(testSimpleH.SetBytesExt(wrapInt64Typ, 16, &tI64Ext))
- chkErr(testMsgpackH.SetBytesExt(wrapInt64Typ, 16, &tI64Ext))
- chkErr(testBincH.SetBytesExt(wrapInt64Typ, 16, &tI64Ext))
- chkErr(testJsonH.SetInterfaceExt(wrapInt64Typ, 16, &tI64Ext))
- chkErr(testCborH.SetInterfaceExt(wrapInt64Typ, 16, &tI64Ext))
- // primitives MUST be an even number, so it can be used as a mapBySlice also.
- primitives := []interface{}{
- int8(-8),
- int16(-1616),
- int32(-32323232),
- int64(-6464646464646464),
- uint8(192),
- uint16(1616),
- uint32(32323232),
- uint64(6464646464646464),
- byte(192),
- float32(-3232.0),
- float64(-6464646464.0),
- float32(3232.0),
- float64(6464.0),
- float64(6464646464.0),
- false,
- true,
- "null",
- nil,
- "some&day>some<day",
- timeToCompare1,
- "",
- timeToCompare2,
- "bytestring",
- timeToCompare3,
- "none",
- timeToCompare4,
- }
- maps := []interface{}{
- map[string]bool{
- "true": true,
- "false": false,
- },
- map[string]interface{}{
- "true": "True",
- "false": false,
- "uint16(1616)": uint16(1616),
- },
- //add a complex combo map in here. (map has list which has map)
- //note that after the first thing, everything else should be generic.
- map[string]interface{}{
- "list": []interface{}{
- int16(1616),
- int32(32323232),
- true,
- float32(-3232.0),
- map[string]interface{}{
- "TRUE": true,
- "FALSE": false,
- },
- []interface{}{true, false},
- },
- "int32": int32(32323232),
- "bool": true,
- "LONG STRING": `
- 1234567890 1234567890
- 1234567890 1234567890
- 1234567890 1234567890
- ABCDEDFGHIJKLMNOPQRSTUVWXYZ
- abcdedfghijklmnopqrstuvwxyz
- ABCDEDFGHIJKLMNOPQRSTUVWXYZ
- abcdedfghijklmnopqrstuvwxyz
- "ABCDEDFGHIJKLMNOPQRSTUVWXYZ"
- ' a tab '
- \a\b\c\d\e
- \b\f\n\r\t all literally
- ugorji
- `,
- "SHORT STRING": "1234567890",
- },
- map[interface{}]interface{}{
- true: "true",
- uint8(138): false,
- false: uint8(200),
- },
- }
- testTableNumPrimitives = len(primitives)
- testTableIdxTime = testTableNumPrimitives - 8
- testTableNumMaps = len(maps)
- table = []interface{}{}
- table = append(table, primitives...)
- table = append(table, primitives)
- table = append(table, testMbsT(primitives))
- table = append(table, maps...)
- table = append(table, newTestStrucFlex(0, testNumRepeatString, false, !testSkipIntf, testMapStringKeyOnly))
- // table = append(table, newTestStrucFlex(0, testNumRepeatString, true, !testSkipIntf, testMapStringKeyOnly))
- }
- func testTableVerify(f testVerifyFlag, h Handle) (av []interface{}) {
- av = make([]interface{}, len(table))
- lp := testTableNumPrimitives + 4
- // doNil := f & testVerifyDoNil == testVerifyDoNil
- // doPython := f & testVerifyForPython == testVerifyForPython
- switch {
- case f.isset(testVerifyForPython):
- for i, v := range table {
- if i == testTableNumPrimitives+1 || i > lp { // testTableNumPrimitives+1 is the mapBySlice
- av[i] = skipVerifyVal
- continue
- }
- av[i] = testVerifyVal(v, f, h)
- }
- // only do the python verify up to the maps, skipping the last 2 maps.
- av = av[:testTableNumPrimitives+2+testTableNumMaps-2]
- case f.isset(testVerifyDoNil):
- for i, v := range table {
- if i > lp {
- av[i] = skipVerifyVal
- continue
- }
- av[i] = testVerifyVal(v, f, h)
- }
- default:
- for i, v := range table {
- if i == lp {
- av[i] = skipVerifyVal
- continue
- }
- //av[i] = testVerifyVal(v, testVerifyMapTypeSame)
- switch v.(type) {
- case []interface{}:
- av[i] = testVerifyVal(v, f, h)
- case testMbsT:
- av[i] = testVerifyVal(v, f, h)
- case map[string]interface{}:
- av[i] = testVerifyVal(v, f, h)
- case map[interface{}]interface{}:
- av[i] = testVerifyVal(v, f, h)
- case time.Time:
- av[i] = testVerifyVal(v, f, h)
- default:
- av[i] = v
- }
- }
- }
- return
- }
- func testVerifyValInt(v int64, isMsgp bool) (v2 interface{}) {
- if isMsgp {
- if v >= 0 && v <= 127 {
- v2 = uint64(v)
- } else {
- v2 = int64(v)
- }
- } else if v >= 0 {
- v2 = uint64(v)
- } else {
- v2 = int64(v)
- }
- return
- }
- func testVerifyVal(v interface{}, f testVerifyFlag, h Handle) (v2 interface{}) {
- //for python msgpack,
- // - all positive integers are unsigned 64-bit ints
- // - all floats are float64
- _, isMsgp := h.(*MsgpackHandle)
- _, isCbor := h.(*CborHandle)
- switch iv := v.(type) {
- case int8:
- v2 = testVerifyValInt(int64(iv), isMsgp)
- // fmt.Printf(">>>> is msgp: %v, v: %T, %v ==> v2: %T, %v\n", isMsgp, v, v, v2, v2)
- case int16:
- v2 = testVerifyValInt(int64(iv), isMsgp)
- case int32:
- v2 = testVerifyValInt(int64(iv), isMsgp)
- case int64:
- v2 = testVerifyValInt(int64(iv), isMsgp)
- case uint8:
- v2 = uint64(iv)
- case uint16:
- v2 = uint64(iv)
- case uint32:
- v2 = uint64(iv)
- case uint64:
- v2 = uint64(iv)
- case float32:
- v2 = float64(iv)
- case float64:
- v2 = float64(iv)
- case []interface{}:
- m2 := make([]interface{}, len(iv))
- for j, vj := range iv {
- m2[j] = testVerifyVal(vj, f, h)
- }
- v2 = m2
- case testMbsT:
- m2 := make([]interface{}, len(iv))
- for j, vj := range iv {
- m2[j] = testVerifyVal(vj, f, h)
- }
- v2 = testMbsT(m2)
- case map[string]bool:
- switch {
- case f.isset(testVerifyMapTypeSame):
- m2 := make(map[string]bool)
- for kj, kv := range iv {
- m2[kj] = kv
- }
- v2 = m2
- case f.isset(testVerifyMapTypeStrIntf):
- m2 := make(map[string]interface{})
- for kj, kv := range iv {
- m2[kj] = kv
- }
- v2 = m2
- case f.isset(testVerifyMapTypeIntfIntf):
- m2 := make(map[interface{}]interface{})
- for kj, kv := range iv {
- m2[kj] = kv
- }
- v2 = m2
- }
- case map[string]interface{}:
- switch {
- case f.isset(testVerifyMapTypeSame):
- m2 := make(map[string]interface{})
- for kj, kv := range iv {
- m2[kj] = testVerifyVal(kv, f, h)
- }
- v2 = m2
- case f.isset(testVerifyMapTypeStrIntf):
- m2 := make(map[string]interface{})
- for kj, kv := range iv {
- m2[kj] = testVerifyVal(kv, f, h)
- }
- v2 = m2
- case f.isset(testVerifyMapTypeIntfIntf):
- m2 := make(map[interface{}]interface{})
- for kj, kv := range iv {
- m2[kj] = testVerifyVal(kv, f, h)
- }
- v2 = m2
- }
- case map[interface{}]interface{}:
- m2 := make(map[interface{}]interface{})
- for kj, kv := range iv {
- m2[testVerifyVal(kj, f, h)] = testVerifyVal(kv, f, h)
- }
- v2 = m2
- case time.Time:
- switch {
- case f.isset(testVerifyTimeAsInteger):
- if iv2 := iv.UnixNano(); iv2 >= 0 {
- v2 = uint64(iv2)
- } else {
- v2 = int64(iv2)
- }
- case isMsgp:
- v2 = iv.UTC()
- case isCbor:
- // fmt.Printf("%%%% cbor verifier\n")
- v2 = iv.UTC().Round(time.Microsecond)
- default:
- v2 = v
- }
- default:
- v2 = v
- }
- return
- }
- func testUnmarshal(v interface{}, data []byte, h Handle) (err error) {
- return testCodecDecode(data, v, h)
- }
- func testMarshal(v interface{}, h Handle) (bs []byte, err error) {
- return testCodecEncode(v, nil, testByteBuf, h)
- }
- func testMarshalErr(v interface{}, h Handle, t *testing.T, name string) (bs []byte) {
- // t.Helper()
- bs, err := testMarshal(v, h)
- if err != nil {
- t.Logf("%s: marshal failed: %v", name, err)
- if testVerbose {
- t.Logf("Error encoding %s: %v, Err: %v", name, v, err)
- }
- t.FailNow()
- }
- return
- }
- func testUnmarshalErr(v interface{}, data []byte, h Handle, t *testing.T, name string) {
- // t.Helper()
- if err := testUnmarshal(v, data, h); err != nil {
- t.Logf("%s: unmarshal failed: %v", name, err)
- if testVerbose {
- t.Logf("Error Decoding into %s: %v, Err: %v", name, v, err)
- }
- t.FailNow()
- }
- }
- func testDeepEqualErr(v1, v2 interface{}, t *testing.T, name string) {
- // t.Helper()
- if err := deepEqual(v1, v2); err == nil {
- if testVerbose {
- t.Logf("%s: values equal", name)
- }
- } else {
- t.Logf("%s: values not equal: %v", name, err)
- if testVerbose {
- t.Logf("%s: values not equal: %v. 1: %#v, 2: %#v", name, err, v1, v2)
- }
- t.FailNow()
- }
- }
- func testReadWriteCloser(c io.ReadWriteCloser) io.ReadWriteCloser {
- if testRpcBufsize <= 0 && rand.Int63()%2 == 0 {
- return c
- }
- return struct {
- io.Closer
- *bufio.Reader
- *bufio.Writer
- }{c, bufio.NewReaderSize(c, testRpcBufsize), bufio.NewWriterSize(c, testRpcBufsize)}
- }
- // doTestCodecTableOne allows us test for different variations based on arguments passed.
- func doTestCodecTableOne(t *testing.T, testNil bool, h Handle,
- vs []interface{}, vsVerify []interface{}) {
- //if testNil, then just test for when a pointer to a nil interface{} is passed. It should work.
- //Current setup allows us test (at least manually) the nil interface or typed interface.
- if testVerbose {
- t.Logf("================ TestNil: %v ================\n", testNil)
- }
- for i, v0 := range vs {
- if testVerbose {
- t.Logf("..............................................")
- t.Logf(" Testing: #%d:, %T, %#v\n", i, v0, v0)
- }
- // if a TestStrucFlex and we are doing a testNil,
- // ensure the fields which are not encodeable are set to nil appropriately
- // i.e. MstrUi64TSelf
- var mapMstrUi64TSelf map[stringUint64T]*stringUint64T
- var mapMsu2wss map[stringUint64T]wrapStringSlice
- tsflex, _ := v0.(*TestStrucFlex)
- if testNil && tsflex != nil {
- mapMstrUi64TSelf = tsflex.MstrUi64TSelf
- mapMsu2wss = tsflex.Msu2wss
- tsflex.MstrUi64TSelf = nil
- tsflex.Msu2wss = nil
- }
- b0 := testMarshalErr(v0, h, t, "v0")
- var b1 = b0
- if len(b1) > 256 {
- b1 = b1[:256]
- }
- if testVerbose {
- if h.isBinary() {
- t.Logf(" Encoded bytes: len: %v, %v\n", len(b0), b1)
- } else {
- t.Logf(" Encoded string: len: %v, %s\n", len(b0), b0)
- // println("########### encoded string: " + string(b0))
- }
- }
- var v1 interface{}
- var err error
- if testNil {
- err = testUnmarshal(&v1, b0, h)
- if tsflex != nil {
- tsflex.MstrUi64TSelf = mapMstrUi64TSelf
- tsflex.Msu2wss = mapMsu2wss
- }
- } else {
- if v0 != nil {
- v0rt := reflect.TypeOf(v0) // ptr
- if v0rt.Kind() == reflect.Ptr {
- err = testUnmarshal(v0, b0, h)
- v1 = v0
- } else {
- rv1 := reflect.New(v0rt)
- err = testUnmarshal(rv1.Interface(), b0, h)
- v1 = rv1.Elem().Interface()
- // v1 = reflect.Indirect(rv4i(v1)).Interface()
- }
- }
- }
- if testVerbose {
- t.Logf(" v1 returned: %T, %v %#v", v1, v1, v1)
- }
- // if v1 != nil {
- // t.Logf(" v1 returned: %T, %#v", v1, v1)
- // //we always indirect, because ptr to typed value may be passed (if not testNil)
- // v1 = reflect.Indirect(rv4i(v1)).Interface()
- // }
- if err != nil {
- t.Logf("-------- Error: %v. Partial return: %v", err, v1)
- t.FailNow()
- }
- v0check := vsVerify[i]
- if v0check == skipVerifyVal {
- if testVerbose {
- t.Logf(" Nil Check skipped: Decoded: %T, %#v\n", v1, v1)
- }
- continue
- }
- if err = deepEqual(v0check, v1); err == nil {
- t.Logf("++++++++ Before and After marshal matched\n")
- } else {
- // t.Logf("-------- Before and After marshal do not match: Error: %v"+
- // " ====> GOLDEN: (%T) %#v, DECODED: (%T) %#v\n", err, v0check, v0check, v1, v1)
- t.Logf("-------- FAIL: Before and After marshal do not match: Error: %v", err)
- if testVerbose {
- t.Logf(" ....... GOLDEN: (%T) %v %#v", v0check, v0check, v0check)
- t.Logf(" ....... DECODED: (%T) %v %#v", v1, v1, v1)
- }
- t.FailNow()
- }
- }
- }
- func testCodecTableOne(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- // func TestMsgpackAllExperimental(t *testing.T) {
- // dopts := testDecOpts(nil, nil, false, true, true),
- numPrim, numMap, idxTime, idxMap := testTableNumPrimitives, testTableNumMaps, testTableIdxTime, testTableNumPrimitives+2
- //println("#################")
- tableVerify := testTableVerify(testVerifyMapTypeSame, h)
- tableTestNilVerify := testTableVerify(testVerifyDoNil|testVerifyMapTypeStrIntf, h)
- switch v := h.(type) {
- case *MsgpackHandle:
- var oldWriteExt bool
- _ = oldWriteExt
- oldWriteExt = v.WriteExt
- v.WriteExt = true
- doTestCodecTableOne(t, false, h, table, tableVerify)
- v.WriteExt = oldWriteExt
- case *JsonHandle:
- //skip []interface{} containing time.Time, as it encodes as a number, but cannot decode back to time.Time.
- //As there is no real support for extension tags in json, this must be skipped.
- doTestCodecTableOne(t, false, h, table[:numPrim], tableVerify[:numPrim])
- doTestCodecTableOne(t, false, h, table[idxMap:], tableVerify[idxMap:])
- default:
- doTestCodecTableOne(t, false, h, table, tableVerify)
- }
- // func TestMsgpackAll(t *testing.T) {
- // //skip []interface{} containing time.Time
- // doTestCodecTableOne(t, false, h, table[:numPrim], tableVerify[:numPrim])
- // doTestCodecTableOne(t, false, h, table[numPrim+1:], tableVerify[numPrim+1:])
- // func TestMsgpackNilStringMap(t *testing.T) {
- var oldMapType reflect.Type
- v := basicHandle(h)
- oldMapType, v.MapType = v.MapType, testMapStrIntfTyp
- // defer func() { v.MapType = oldMapType }()
- //skip time.Time, []interface{} containing time.Time, last map, and newStruc
- doTestCodecTableOne(t, true, h, table[:idxTime], tableTestNilVerify[:idxTime])
- doTestCodecTableOne(t, true, h, table[idxMap:idxMap+numMap-1], tableTestNilVerify[idxMap:idxMap+numMap-1]) // failing one for msgpack
- v.MapType = oldMapType
- // func TestMsgpackNilIntf(t *testing.T) {
- //do last map and newStruc
- idx2 := idxMap + numMap - 1
- doTestCodecTableOne(t, true, h, table[idx2:], tableTestNilVerify[idx2:])
- //TODO? What is this one?
- //doTestCodecTableOne(t, true, h, table[17:18], tableTestNilVerify[17:18])
- }
- func testCodecMiscOne(t *testing.T, h Handle) {
- var err error
- testOnce.Do(testInitAll)
- b := testMarshalErr(32, h, t, "32")
- // Cannot do this nil one, because faster type assertion decoding will panic
- // var i *int32
- // if err = testUnmarshal(b, i, nil); err == nil {
- // t.Logf("------- Expecting error because we cannot unmarshal to int32 nil ptr")
- // t.FailNow()
- // }
- var i2 int32
- testUnmarshalErr(&i2, b, h, t, "int32-ptr")
- if i2 != int32(32) {
- t.Logf("------- didn't unmarshal to 32: Received: %d", i2)
- t.FailNow()
- }
- // func TestMsgpackDecodePtr(t *testing.T) {
- ts := newTestStrucFlex(testDepth, testNumRepeatString, false, !testSkipIntf, testMapStringKeyOnly)
- b = testMarshalErr(ts, h, t, "pointer-to-struct")
- if len(b) < 40 {
- t.Logf("------- Size must be > 40. Size: %d", len(b))
- t.FailNow()
- }
- var b1 = b
- if len(b1) > 256 {
- b1 = b1[:256]
- }
- if testVerbose {
- if h.isBinary() {
- t.Logf("------- b: size: %v, value: %v", len(b), b1)
- } else {
- t.Logf("------- b: size: %v, value: %s", len(b), b1)
- }
- }
- ts2 := emptyTestStrucFlex()
- testUnmarshalErr(ts2, b, h, t, "pointer-to-struct")
- if ts2.I64 != math.MaxInt64*2/3 {
- t.Logf("------- Unmarshal wrong. Expect I64 = 64. Got: %v", ts2.I64)
- t.FailNow()
- }
- // func TestMsgpackIntfDecode(t *testing.T) {
- m := map[string]int{"A": 2, "B": 3}
- p := []interface{}{m}
- bs := testMarshalErr(p, h, t, "p")
- m2 := map[string]int{}
- p2 := []interface{}{m2}
- testUnmarshalErr(&p2, bs, h, t, "&p2")
- if m2["A"] != 2 || m2["B"] != 3 {
- t.Logf("FAIL: m2 not as expected: expecting: %v, got: %v", m, m2)
- t.FailNow()
- }
- // log("m: %v, m2: %v, p: %v, p2: %v", m, m2, p, p2)
- checkEqualT(t, p, p2, "p=p2")
- checkEqualT(t, m, m2, "m=m2")
- if err = deepEqual(p, p2); err == nil {
- if testVerbose {
- t.Logf("p and p2 match")
- }
- } else {
- t.Logf("Not Equal: %v. p: %v, p2: %v", err, p, p2)
- t.FailNow()
- }
- if err = deepEqual(m, m2); err == nil {
- if testVerbose {
- t.Logf("m and m2 match")
- }
- } else {
- t.Logf("Not Equal: %v. m: %v, m2: %v", err, m, m2)
- t.FailNow()
- }
- // func TestMsgpackDecodeStructSubset(t *testing.T) {
- // test that we can decode a subset of the stream
- mm := map[string]interface{}{"A": 5, "B": 99, "C": 333}
- bs = testMarshalErr(mm, h, t, "mm")
- type ttt struct {
- A uint8
- C int32
- }
- var t2 ttt
- testUnmarshalErr(&t2, bs, h, t, "t2")
- t3 := ttt{5, 333}
- checkEqualT(t, t2, t3, "t2=t3")
- // println(">>>>>")
- // test simple arrays, non-addressable arrays, slices
- type tarr struct {
- A int64
- B [3]int64
- C []byte
- D [3]byte
- }
- var tarr0 = tarr{1, [3]int64{2, 3, 4}, []byte{4, 5, 6}, [3]byte{7, 8, 9}}
- // test both pointer and non-pointer (value)
- for _, tarr1 := range []interface{}{tarr0, &tarr0} {
- bs = testMarshalErr(tarr1, h, t, "tarr1")
- if _, ok := h.(*JsonHandle); ok {
- if testVerbose {
- t.Logf("Marshal as: %s", bs)
- }
- }
- var tarr2 tarr
- testUnmarshalErr(&tarr2, bs, h, t, "tarr2")
- checkEqualT(t, tarr0, tarr2, "tarr0=tarr2")
- }
- // test byte array, even if empty (msgpack only)
- if h == testMsgpackH {
- type ystruct struct {
- Anarray []byte
- }
- var ya = ystruct{}
- testUnmarshalErr(&ya, []byte{0x91, 0x90}, h, t, "ya")
- }
- var tt1, tt2 time.Time
- tt2 = time.Now()
- bs = testMarshalErr(tt1, h, t, "zero-time-enc")
- testUnmarshalErr(&tt2, bs, h, t, "zero-time-dec")
- testDeepEqualErr(tt1, tt2, t, "zero-time-eq")
- // test encoding a slice of byte (but not []byte) and decoding into a []byte
- var sw = []wrapUint8{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'}
- var bw []byte // ("ABCDEFGHIJ")
- bs = testMarshalErr(sw, h, t, "wrap-bytes-enc")
- testUnmarshalErr(&bw, bs, h, t, "wrap-bytes-dec")
- testDeepEqualErr(bw, []byte("ABCDEFGHIJ"), t, "wrap-bytes-eq")
- }
- func testCodecEmbeddedPointer(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- type Z int
- type A struct {
- AnInt int
- }
- type B struct {
- *Z
- *A
- MoreInt int
- }
- var z Z = 4
- x1 := &B{&z, &A{5}, 6}
- bs := testMarshalErr(x1, h, t, "x1")
- var x2 = new(B)
- testUnmarshalErr(x2, bs, h, t, "x2")
- checkEqualT(t, x1, x2, "x1=x2")
- }
- func testCodecUnderlyingType(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- // Manual Test.
- // Run by hand, with accompanying printf.statements in fast-path.go
- // to ensure that the fast functions are called.
- type T1 map[string]string
- v := T1{"1": "1s", "2": "2s"}
- var bs []byte
- var err error
- NewEncoderBytes(&bs, h).MustEncode(v)
- if err != nil {
- t.Logf("Error during encode: %v", err)
- t.FailNow()
- }
- var v2 T1
- NewDecoderBytes(bs, h).MustDecode(&v2)
- if err != nil {
- t.Logf("Error during decode: %v", err)
- t.FailNow()
- }
- }
- func testCodecChan(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- // - send a slice []*int64 (sl1) into an chan (ch1) with cap > len(s1)
- // - encode ch1 as a stream array
- // - decode a chan (ch2), with cap > len(s1) from the stream array
- // - receive from ch2 into slice sl2
- // - compare sl1 and sl2
- // - do this for codecs: json, cbor (covers all types)
- {
- if testVerbose {
- t.Logf("*int64")
- }
- sl1 := make([]*int64, 4)
- for i := range sl1 {
- var j int64 = int64(i)
- sl1[i] = &j
- }
- ch1 := make(chan *int64, 4)
- for _, j := range sl1 {
- ch1 <- j
- }
- var bs []byte
- NewEncoderBytes(&bs, h).MustEncode(ch1)
- ch2 := make(chan *int64, 8)
- NewDecoderBytes(bs, h).MustDecode(&ch2)
- close(ch2)
- var sl2 []*int64
- for j := range ch2 {
- sl2 = append(sl2, j)
- }
- if err := deepEqual(sl1, sl2); err != nil {
- t.Logf("FAIL: Not Match: %v; len: %v, %v", err, len(sl1), len(sl2))
- if testVerbose {
- t.Logf("sl1: %#v, sl2: %#v", sl1, sl2)
- }
- t.FailNow()
- }
- }
- {
- if testVerbose {
- t.Logf("testBytesT []byte - input []byte")
- }
- type testBytesT []byte
- sl1 := make([]testBytesT, 4)
- for i := range sl1 {
- var j = []byte(strings.Repeat(strconv.FormatInt(int64(i), 10), i))
- sl1[i] = j
- }
- ch1 := make(chan testBytesT, 4)
- for _, j := range sl1 {
- ch1 <- j
- }
- var bs []byte
- NewEncoderBytes(&bs, h).MustEncode(ch1)
- ch2 := make(chan testBytesT, 8)
- NewDecoderBytes(bs, h).MustDecode(&ch2)
- close(ch2)
- var sl2 []testBytesT
- for j := range ch2 {
- // t.Logf(">>>> from chan: is nil? %v, %v", j == nil, j)
- sl2 = append(sl2, j)
- }
- if err := deepEqual(sl1, sl2); err != nil {
- t.Logf("FAIL: Not Match: %v; len: %v, %v", err, len(sl1), len(sl2))
- if testVerbose {
- t.Logf("sl1: %#v, sl2: %#v", sl1, sl2)
- }
- t.FailNow()
- }
- }
- {
- if testVerbose {
- t.Logf("testBytesT byte - input string/testBytesT")
- }
- type testBytesT byte
- sl1 := make([]testBytesT, 4)
- for i := range sl1 {
- var j = strconv.FormatInt(int64(i), 10)[0]
- sl1[i] = testBytesT(j)
- }
- ch1 := make(chan testBytesT, 4)
- for _, j := range sl1 {
- ch1 <- j
- }
- var bs []byte
- NewEncoderBytes(&bs, h).MustEncode(ch1)
- ch2 := make(chan testBytesT, 8)
- NewDecoderBytes(bs, h).MustDecode(&ch2)
- close(ch2)
- var sl2 []testBytesT
- for j := range ch2 {
- sl2 = append(sl2, j)
- }
- if err := deepEqual(sl1, sl2); err != nil {
- t.Logf("FAIL: Not Match: %v; len: %v, %v", err, len(sl1), len(sl2))
- t.FailNow()
- }
- }
- {
- if testVerbose {
- t.Logf("*[]byte")
- }
- sl1 := make([]byte, 4)
- for i := range sl1 {
- var j = strconv.FormatInt(int64(i), 10)[0]
- sl1[i] = byte(j)
- }
- ch1 := make(chan byte, 4)
- for _, j := range sl1 {
- ch1 <- j
- }
- var bs []byte
- NewEncoderBytes(&bs, h).MustEncode(ch1)
- ch2 := make(chan byte, 8)
- NewDecoderBytes(bs, h).MustDecode(&ch2)
- close(ch2)
- var sl2 []byte
- for j := range ch2 {
- sl2 = append(sl2, j)
- }
- if err := deepEqual(sl1, sl2); err != nil {
- t.Logf("FAIL: Not Match: %v; len: %v, %v", err, len(sl1), len(sl2))
- t.FailNow()
- }
- }
- }
- func testCodecRpcOne(t *testing.T, rr Rpc, h Handle, doRequest bool, exitSleepMs time.Duration,
- ) (port int) {
- testOnce.Do(testInitAll)
- if testSkipRPCTests {
- return
- }
- // rpc needs EOF, which is sent via a panic, and so must be recovered.
- if !recoverPanicToErr {
- t.Logf("EXPECTED. set recoverPanicToErr=true, since rpc needs EOF")
- t.FailNow()
- }
- if jsonH, ok := h.(*JsonHandle); ok && !jsonH.TermWhitespace {
- jsonH.TermWhitespace = true
- defer func() { jsonH.TermWhitespace = false }()
- }
- srv := rpc.NewServer()
- srv.Register(testRpcInt)
- ln, err := net.Listen("tcp", "127.0.0.1:0") // listen on ipv4 localhost
- t.Logf("connFn: addr: %v, network: %v, port: %v", ln.Addr(), ln.Addr().Network(), (ln.Addr().(*net.TCPAddr)).Port)
- // log("listener: %v", ln.Addr())
- checkErrT(t, err)
- port = (ln.Addr().(*net.TCPAddr)).Port
- // var opts *DecoderOptions
- // opts := testDecOpts
- // opts.MapType = mapStrIntfTyp
- serverExitChan := make(chan bool, 1)
- var serverExitFlag uint64
- serverFn := func() {
- for {
- conn1, err1 := ln.Accept()
- // if err1 != nil {
- // //fmt.Printf("accept err1: %v\n", err1)
- // continue
- // }
- if atomic.LoadUint64(&serverExitFlag) == 1 {
- serverExitChan <- true
- if conn1 != nil {
- conn1.Close()
- }
- return // exit serverFn goroutine
- }
- if err1 == nil && conn1 != nil {
- sc := rr.ServerCodec(testReadWriteCloser(conn1), h)
- srv.ServeCodec(sc)
- }
- }
- }
- clientFn := func(cc rpc.ClientCodec) {
- cl := rpc.NewClientWithCodec(cc)
- defer cl.Close()
- // defer func() { println("##### client closing"); cl.Close() }()
- var up, sq, mult int
- var rstr string
- // log("Calling client")
- checkErrT(t, cl.Call("TestRpcInt.Update", 5, &up))
- // log("Called TestRpcInt.Update")
- checkEqualT(t, testRpcInt.i, 5, "testRpcInt.i=5")
- checkEqualT(t, up, 5, "up=5")
- checkErrT(t, cl.Call("TestRpcInt.Square", 1, &sq))
- checkEqualT(t, sq, 25, "sq=25")
- checkErrT(t, cl.Call("TestRpcInt.Mult", 20, &mult))
- checkEqualT(t, mult, 100, "mult=100")
- checkErrT(t, cl.Call("TestRpcInt.EchoStruct", TestRpcABC{"Aa", "Bb", "Cc"}, &rstr))
- checkEqualT(t, rstr, fmt.Sprintf("%#v", TestRpcABC{"Aa", "Bb", "Cc"}), "rstr=")
- checkErrT(t, cl.Call("TestRpcInt.Echo123", []string{"A1", "B2", "C3"}, &rstr))
- checkEqualT(t, rstr, fmt.Sprintf("%#v", []string{"A1", "B2", "C3"}), "rstr=")
- }
- connFn := func() (bs net.Conn) {
- // log("calling f1")
- bs, err2 := net.Dial(ln.Addr().Network(), ln.Addr().String())
- checkErrT(t, err2)
- return
- }
- exitFn := func() {
- atomic.StoreUint64(&serverExitFlag, 1)
- bs := connFn()
- <-serverExitChan
- bs.Close()
- // serverExitChan <- true
- }
- go serverFn()
- runtime.Gosched()
- //time.Sleep(100 * time.Millisecond)
- if exitSleepMs == 0 {
- defer ln.Close()
- defer exitFn()
- }
- if doRequest {
- bs := connFn()
- cc := rr.ClientCodec(testReadWriteCloser(bs), h)
- clientFn(cc)
- }
- if exitSleepMs != 0 {
- go func() {
- defer ln.Close()
- time.Sleep(exitSleepMs)
- exitFn()
- }()
- }
- return
- }
- func doTestMapEncodeForCanonical(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- // println("doTestMapEncodeForCanonical")
- v1 := map[stringUint64T]interface{}{
- stringUint64T{"a", 1}: 1,
- stringUint64T{"b", 2}: "hello",
- stringUint64T{"c", 3}: map[string]interface{}{
- "c/a": 1,
- "c/b": "world",
- "c/c": []int{1, 2, 3, 4},
- "c/d": map[string]interface{}{
- "c/d/a": "fdisajfoidsajfopdjsaopfjdsapofda",
- "c/d/b": "fdsafjdposakfodpsakfopdsakfpodsakfpodksaopfkdsopafkdopsa",
- "c/d/c": "poir02 ir30qif4p03qir0pogjfpoaerfgjp ofke[padfk[ewapf kdp[afep[aw",
- "c/d/d": "fdsopafkd[sa f-32qor-=4qeof -afo-erfo r-eafo 4e- o r4-qwo ag",
- "c/d/e": "kfep[a sfkr0[paf[a foe-[wq ewpfao-q ro3-q ro-4qof4-qor 3-e orfkropzjbvoisdb",
- "c/d/f": "",
- },
- "c/e": map[int]string{
- 1: "1",
- 22: "22",
- 333: "333",
- 4444: "4444",
- 55555: "55555",
- },
- "c/f": map[string]int{
- "1": 1,
- "22": 22,
- "333": 333,
- "4444": 4444,
- "55555": 55555,
- },
- "c/g": map[bool]int{
- false: 0,
- true: 1,
- },
- "c/t": map[time.Time]int64{
- time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC): time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC).UnixNano(),
- time.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC): time.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC).UnixNano(),
- time.Date(2017, 1, 1, 0, 0, 0, 0, time.UTC): time.Date(2017, 1, 1, 0, 0, 0, 0, time.UTC).UnixNano(),
- },
- },
- }
- var v2 map[stringUint64T]interface{}
- var b1, b2, b3 []byte
- // encode v1 into b1, decode b1 into v2, encode v2 into b2, and compare b1 and b2.
- // OR
- // encode v1 into b1, decode b1 into v2, encode v2 into b2 and b3, and compare b2 and b3.
- // e.g. when doing cbor indefinite, we may haveto use out-of-band encoding
- // where each key is encoded as an indefinite length string, which makes it not the same
- // order as the strings were lexicographically ordered before.
- var cborIndef bool
- if ch, ok := h.(*CborHandle); ok {
- cborIndef = ch.IndefiniteLength
- }
- bh := basicHandle(h)
- if !bh.Canonical {
- bh.Canonical = true
- defer func() { bh.Canonical = false }()
- }
- e1 := NewEncoderBytes(&b1, h)
- e1.MustEncode(v1)
- d1 := NewDecoderBytes(b1, h)
- d1.MustDecode(&v2)
- // testDeepEqualErr(v1, v2, t, "huh?")
- e2 := NewEncoderBytes(&b2, h)
- e2.MustEncode(v2)
- var b1t, b2t = b1, b2
- if cborIndef {
- e2 = NewEncoderBytes(&b3, h)
- e2.MustEncode(v2)
- b1t, b2t = b2, b3
- }
- if !bytes.Equal(b1t, b2t) {
- t.Logf("Unequal bytes: %v VS %v", b1t, b2t)
- t.FailNow()
- }
- }
- func doTestStdEncIntf(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- args := [][2]interface{}{
- {&TestABC{"A", "BB", "CCC"}, new(TestABC)},
- {&TestABC2{"AAA", "BB", "C"}, new(TestABC2)},
- }
- for _, a := range args {
- var b []byte
- e := NewEncoderBytes(&b, h)
- e.MustEncode(a[0])
- d := NewDecoderBytes(b, h)
- d.MustDecode(a[1])
- if err := deepEqual(a[0], a[1]); err == nil {
- if testVerbose {
- t.Logf("++++ Objects match")
- }
- } else {
- t.Logf("---- FAIL: Objects do not match: y0: %v, y1: %v, err: %v", a[0], a[1], err)
- t.FailNow()
- }
- }
- }
- func doTestEncCircularRef(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- type T1 struct {
- S string
- B bool
- T interface{}
- }
- type T2 struct {
- S string
- T *T1
- }
- type T3 struct {
- S string
- T *T2
- }
- t1 := T1{"t1", true, nil}
- t2 := T2{"t2", &t1}
- t3 := T3{"t3", &t2}
- t1.T = &t3
- var bs []byte
- var err error
- bh := basicHandle(h)
- if !bh.CheckCircularRef {
- bh.CheckCircularRef = true
- defer func() { bh.CheckCircularRef = false }()
- }
- err = NewEncoderBytes(&bs, h).Encode(&t3)
- if err == nil {
- t.Logf("expecting error due to circular reference. found none")
- t.FailNow()
- }
- if x := err.Error(); strings.Contains(x, "circular") || strings.Contains(x, "cyclic") {
- if testVerbose {
- t.Logf("error detected as expected: %v", x)
- }
- } else {
- t.Logf("FAIL: error detected was not as expected: %v", x)
- t.FailNow()
- }
- }
- // TestAnonCycleT{1,2,3} types are used to test anonymous cycles.
- // They are top-level, so that they can have circular references.
- type (
- TestAnonCycleT1 struct {
- S string
- TestAnonCycleT2
- }
- TestAnonCycleT2 struct {
- S2 string
- TestAnonCycleT3
- }
- TestAnonCycleT3 struct {
- *TestAnonCycleT1
- }
- )
- func doTestAnonCycle(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- var x TestAnonCycleT1
- x.S = "hello"
- x.TestAnonCycleT2.S2 = "hello.2"
- x.TestAnonCycleT2.TestAnonCycleT3.TestAnonCycleT1 = &x
- // just check that you can get typeInfo for T1
- rt := reflect.TypeOf((*TestAnonCycleT1)(nil)).Elem()
- rtid := rt2id(rt)
- pti := basicHandle(h).getTypeInfo(rtid, rt)
- if testVerbose {
- t.Logf("[%s] pti: %v", h.Name(), pti)
- }
- }
- func doTestErrWriter(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- name := h.Name()
- var ew testErrWriter
- w := bufio.NewWriterSize(&ew, 4)
- enc := NewEncoder(w, h)
- for i := 0; i < 4; i++ {
- err := enc.Encode("ugorji")
- if ev, ok := err.(encodeError); ok {
- err = ev.Cause()
- }
- if err != testErrWriterErr {
- t.Logf("%s: expecting err: %v, received: %v", name, testErrWriterErr, err)
- t.FailNow()
- }
- }
- }
- func doTestJsonLargeInteger(t *testing.T, v interface{}, ias uint8) {
- testOnce.Do(testInitAll)
- if testVerbose {
- t.Logf("Running doTestJsonLargeInteger: v: %#v, ias: %c", v, ias)
- }
- oldIAS := testJsonH.IntegerAsString
- defer func() { testJsonH.IntegerAsString = oldIAS }()
- testJsonH.IntegerAsString = ias
- var vu uint
- var vi int
- var vb bool
- var b []byte
- e := NewEncoderBytes(&b, testJsonH)
- e.MustEncode(v)
- e.MustEncode(true)
- d := NewDecoderBytes(b, testJsonH)
- // below, we validate that the json string or number was encoded,
- // then decode, and validate that the correct value was decoded.
- fnStrChk := func() {
- // check that output started with ", and ended with " true
- // if !(len(b) >= 7 && b[0] == '"' && string(b[len(b)-7:]) == `" true `) {
- if !(len(b) >= 5 && b[0] == '"' && string(b[len(b)-5:]) == `"true`) {
- t.Logf("Expecting a JSON string, got: '%s'", b)
- t.FailNow()
- }
- }
- switch ias {
- case 'L':
- switch v2 := v.(type) {
- case int:
- v2n := int64(v2) // done to work with 32-bit OS
- if v2n > 1<<53 || (v2n < 0 && -v2n > 1<<53) {
- fnStrChk()
- }
- case uint:
- v2n := uint64(v2) // done to work with 32-bit OS
- if v2n > 1<<53 {
- fnStrChk()
- }
- }
- case 'A':
- fnStrChk()
- default:
- // check that output doesn't contain " at all
- for _, i := range b {
- if i == '"' {
- t.Logf("Expecting a JSON Number without quotation: got: %s", b)
- t.FailNow()
- }
- }
- }
- switch v2 := v.(type) {
- case int:
- d.MustDecode(&vi)
- d.MustDecode(&vb)
- // check that vb = true, and vi == v2
- if !(vb && vi == v2) {
- t.Logf("Expecting equal values from %s: got golden: %v, decoded: %v", b, v2, vi)
- t.FailNow()
- }
- case uint:
- d.MustDecode(&vu)
- d.MustDecode(&vb)
- // check that vb = true, and vi == v2
- if !(vb && vu == v2) {
- t.Logf("Expecting equal values from %s: got golden: %v, decoded: %v", b, v2, vu)
- t.FailNow()
- }
- }
- }
- func doTestRawValue(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- bh := basicHandle(h)
- if !bh.Raw {
- bh.Raw = true
- defer func() { bh.Raw = false }()
- }
- var i, i2 int
- var v, v2 TestRawValue
- var bs, bs2 []byte
- i = 1234 //1234567890
- v = TestRawValue{I: i}
- e := NewEncoderBytes(&bs, h)
- e.MustEncode(v.I)
- if testVerbose {
- t.Logf(">>> raw: %v\n", bs)
- }
- v.R = Raw(bs)
- e.ResetBytes(&bs2)
- e.MustEncode(v)
- if testVerbose {
- t.Logf(">>> bs2: %v\n", bs2)
- }
- d := NewDecoderBytes(bs2, h)
- d.MustDecode(&v2)
- d.ResetBytes(v2.R)
- if testVerbose {
- t.Logf(">>> v2.R: %v\n", ([]byte)(v2.R))
- }
- d.MustDecode(&i2)
- if testVerbose {
- t.Logf(">>> Encoded %v, decoded %v\n", i, i2)
- }
- // t.Logf("Encoded %v, decoded %v", i, i2)
- if i != i2 {
- t.Logf("Error: encoded %v, decoded %v", i, i2)
- t.FailNow()
- }
- }
- // Comprehensive testing that generates data encoded from python handle (cbor, msgpack),
- // and validates that our code can read and write it out accordingly.
- // We keep this unexported here, and put actual test in ext_dep_test.go.
- // This way, it can be excluded by excluding file completely.
- func doTestPythonGenStreams(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- name := h.Name()
- t.Logf("TestPythonGenStreams-%v", name)
- tmpdir, err := ioutil.TempDir("", "golang-"+name+"-test")
- if err != nil {
- t.Logf("-------- Unable to create temp directory\n")
- t.FailNow()
- }
- defer os.RemoveAll(tmpdir)
- if testVerbose {
- t.Logf("tmpdir: %v", tmpdir)
- }
- cmd := exec.Command("python", "test.py", "testdata", tmpdir)
- //cmd.Stdin = strings.NewReader("some input")
- //cmd.Stdout = &out
- var cmdout []byte
- if cmdout, err = cmd.CombinedOutput(); err != nil {
- t.Logf("-------- Error running test.py testdata. Err: %v", err)
- t.Logf(" %v", string(cmdout))
- t.FailNow()
- }
- bh := basicHandle(h)
- oldMapType := bh.MapType
- tablePythonVerify := testTableVerify(testVerifyForPython|testVerifyTimeAsInteger|testVerifyMapTypeStrIntf, h)
- for i, v := range tablePythonVerify {
- // if v == uint64(0) && h == testMsgpackH {
- // v = int64(0)
- // }
- bh.MapType = oldMapType
- //load up the golden file based on number
- //decode it
- //compare to in-mem object
- //encode it again
- //compare to output stream
- if testVerbose {
- t.Logf("..............................................")
- }
- t.Logf(" Testing: #%d: %T, %#v\n", i, v, v)
- var bss []byte
- bss, err = ioutil.ReadFile(filepath.Join(tmpdir, strconv.Itoa(i)+"."+name+".golden"))
- if err != nil {
- t.Logf("-------- Error reading golden file: %d. Err: %v", i, err)
- t.FailNow()
- continue
- }
- bh.MapType = testMapStrIntfTyp
- var v1 interface{}
- if err = testUnmarshal(&v1, bss, h); err != nil {
- t.Logf("-------- Error decoding stream: %d: Err: %v", i, err)
- t.FailNow()
- continue
- }
- if v == skipVerifyVal {
- continue
- }
- //no need to indirect, because we pass a nil ptr, so we already have the value
- //if v1 != nil { v1 = reflect.Indirect(rv4i(v1)).Interface() }
- if err = deepEqual(v, v1); err == nil {
- if testVerbose {
- t.Logf("++++++++ Objects match: %T, %v", v, v)
- }
- } else {
- t.Logf("-------- FAIL: Objects do not match: %v. Source: %T. Decoded: %T", err, v, v1)
- if testVerbose {
- t.Logf("-------- GOLDEN: %#v", v)
- // t.Logf("-------- DECODED: %#v <====> %#v", v1, reflect.Indirect(rv4i(v1)).Interface())
- t.Logf("-------- DECODED: %#v <====> %#v", v1, reflect.Indirect(rv4i(v1)).Interface())
- }
- t.FailNow()
- }
- bsb, err := testMarshal(v1, h)
- if err != nil {
- t.Logf("Error encoding to stream: %d: Err: %v", i, err)
- t.FailNow()
- continue
- }
- if err = deepEqual(bsb, bss); err == nil {
- if testVerbose {
- t.Logf("++++++++ Bytes match")
- }
- } else {
- t.Logf("???????? FAIL: Bytes do not match. %v.", err)
- xs := "--------"
- if rv4i(v).Kind() == reflect.Map {
- xs = " "
- t.Logf("%s It's a map. Ok that they don't match (dependent on ordering).", xs)
- } else {
- t.Logf("%s It's not a map. They should match.", xs)
- t.FailNow()
- }
- if testVerbose {
- t.Logf("%s FROM_FILE: %4d] %v", xs, len(bss), bss)
- t.Logf("%s ENCODED: %4d] %v", xs, len(bsb), bsb)
- }
- }
- }
- bh.MapType = oldMapType
- }
- // To test MsgpackSpecRpc, we test 3 scenarios:
- // - Go Client to Go RPC Service (contained within TestMsgpackRpcSpec)
- // - Go client to Python RPC Service (contained within doTestMsgpackRpcSpecGoClientToPythonSvc)
- // - Python Client to Go RPC Service (contained within doTestMsgpackRpcSpecPythonClientToGoSvc)
- //
- // This allows us test the different calling conventions
- // - Go Service requires only one argument
- // - Python Service allows multiple arguments
- func doTestMsgpackRpcSpecGoClientToPythonSvc(t *testing.T) {
- if testSkipRPCTests {
- return
- }
- testOnce.Do(testInitAll)
- // openPorts are between 6700 and 6800
- r := rand.New(rand.NewSource(time.Now().UnixNano()))
- openPort := strconv.FormatInt(6700+r.Int63n(99), 10)
- // openPort := "6792"
- cmd := exec.Command("python", "test.py", "rpc-server", openPort, "4")
- checkErrT(t, cmd.Start())
- bs, err2 := net.Dial("tcp", ":"+openPort)
- for i := 0; i < 10 && err2 != nil; i++ {
- time.Sleep(50 * time.Millisecond) // time for python rpc server to start
- bs, err2 = net.Dial("tcp", ":"+openPort)
- }
- checkErrT(t, err2)
- cc := MsgpackSpecRpc.ClientCodec(testReadWriteCloser(bs), testMsgpackH)
- cl := rpc.NewClientWithCodec(cc)
- defer cl.Close()
- var rstr string
- checkErrT(t, cl.Call("EchoStruct", TestRpcABC{"Aa", "Bb", "Cc"}, &rstr))
- //checkEqualT(t, rstr, "{'A': 'Aa', 'B': 'Bb', 'C': 'Cc'}")
- var mArgs MsgpackSpecRpcMultiArgs = []interface{}{"A1", "B2", "C3"}
- checkErrT(t, cl.Call("Echo123", mArgs, &rstr))
- checkEqualT(t, rstr, "1:A1 2:B2 3:C3", "rstr=")
- cmd.Process.Kill()
- }
- func doTestMsgpackRpcSpecPythonClientToGoSvc(t *testing.T) {
- if testSkipRPCTests {
- return
- }
- testOnce.Do(testInitAll)
- port := testCodecRpcOne(t, MsgpackSpecRpc, testMsgpackH, false, 1*time.Second)
- //time.Sleep(1000 * time.Millisecond)
- cmd := exec.Command("python", "test.py", "rpc-client-go-service", strconv.Itoa(port))
- var cmdout []byte
- var err error
- if cmdout, err = cmd.CombinedOutput(); err != nil {
- t.Logf("-------- Error running test.py rpc-client-go-service. Err: %v", err)
- t.Logf(" %v", string(cmdout))
- t.FailNow()
- }
- checkEqualT(t, string(cmdout),
- fmt.Sprintf("%#v\n%#v\n", []string{"A1", "B2", "C3"}, TestRpcABC{"Aa", "Bb", "Cc"}), "cmdout=")
- }
- func doTestSwallowAndZero(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- v1 := newTestStrucFlex(testDepth, testNumRepeatString, false, false, testMapStringKeyOnly)
- var b1 []byte
- e1 := NewEncoderBytes(&b1, h)
- e1.MustEncode(v1)
- d1 := NewDecoderBytes(b1, h)
- d1.swallow()
- if d1.r().numread() != uint(len(b1)) {
- t.Logf("swallow didn't consume all encoded bytes: %v out of %v", d1.r().numread(), len(b1))
- t.FailNow()
- }
- setZero(v1)
- testDeepEqualErr(v1, &TestStrucFlex{}, t, "filled-and-zeroed")
- }
- func doTestRawExt(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- var b []byte
- var v RawExt // interface{}
- _, isJson := h.(*JsonHandle)
- _, isCbor := h.(*CborHandle)
- bh := basicHandle(h)
- // isValuer := isJson || isCbor
- // _ = isValuer
- for _, r := range []RawExt{
- {Tag: 99, Value: "9999", Data: []byte("9999")},
- } {
- e := NewEncoderBytes(&b, h)
- e.MustEncode(&r)
- // fmt.Printf(">>>> rawext: isnil? %v, %d - %v\n", b == nil, len(b), b)
- d := NewDecoderBytes(b, h)
- d.MustDecode(&v)
- var r2 = r
- switch {
- case isJson:
- r2.Tag = 0
- r2.Data = nil
- case isCbor:
- r2.Data = nil
- default:
- r2.Value = nil
- }
- testDeepEqualErr(v, r2, t, "rawext-default")
- // switch h.(type) {
- // case *JsonHandle:
- // testDeepEqualErr(r.Value, v, t, "rawext-json")
- // default:
- // var r2 = r
- // if isValuer {
- // r2.Data = nil
- // } else {
- // r2.Value = nil
- // }
- // testDeepEqualErr(v, r2, t, "rawext-default")
- // }
- }
- // Add testing for Raw also
- if b != nil {
- b = b[:0]
- }
- oldRawMode := bh.Raw
- defer func() { bh.Raw = oldRawMode }()
- bh.Raw = true
- var v2 Raw
- for _, s := range []string{
- "goodbye",
- "hello",
- } {
- e := NewEncoderBytes(&b, h)
- e.MustEncode(&s)
- // fmt.Printf(">>>> rawext: isnil? %v, %d - %v\n", b == nil, len(b), b)
- var r Raw = make([]byte, len(b))
- copy(r, b)
- d := NewDecoderBytes(b, h)
- d.MustDecode(&v2)
- testDeepEqualErr(v2, r, t, "raw-default")
- }
- }
- // func doTestTimeExt(t *testing.T, h Handle) {
- // var t = time.Now()
- // // add time ext to the handle
- // }
- func doTestMapStructKey(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- var b []byte
- var v interface{} // map[stringUint64T]wrapUint64Slice // interface{}
- bh := basicHandle(h)
- m := map[stringUint64T]wrapUint64Slice{
- stringUint64T{"55555", 55555}: []wrapUint64{12345},
- stringUint64T{"333", 333}: []wrapUint64{123},
- }
- oldCanonical := bh.Canonical
- oldMapType := bh.MapType
- defer func() {
- bh.Canonical = oldCanonical
- bh.MapType = oldMapType
- }()
- bh.MapType = reflect.TypeOf((*map[stringUint64T]wrapUint64Slice)(nil)).Elem()
- for _, bv := range [2]bool{true, false} {
- b, v = nil, nil
- bh.Canonical = bv
- e := NewEncoderBytes(&b, h)
- e.MustEncode(m)
- d := NewDecoderBytes(b, h)
- d.MustDecode(&v)
- testDeepEqualErr(v, m, t, "map-structkey")
- }
- }
- func doTestDecodeNilMapValue(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- type Struct struct {
- Field map[uint16]map[uint32]struct{}
- }
- bh := basicHandle(h)
- oldMapType := bh.MapType
- oldDeleteOnNilMapValue := bh.DeleteOnNilMapValue
- defer func() {
- bh.MapType = oldMapType
- bh.DeleteOnNilMapValue = oldDeleteOnNilMapValue
- }()
- bh.MapType = reflect.TypeOf(map[interface{}]interface{}(nil))
- bh.DeleteOnNilMapValue = false
- _, isJsonHandle := h.(*JsonHandle)
- toEncode := Struct{Field: map[uint16]map[uint32]struct{}{
- 1: nil,
- }}
- bs, err := testMarshal(toEncode, h)
- if err != nil {
- t.Logf("Error encoding: %v, Err: %v", toEncode, err)
- t.FailNow()
- }
- if isJsonHandle {
- t.Logf("json encoded: %s\n", bs)
- }
- var decoded Struct
- err = testUnmarshal(&decoded, bs, h)
- if err != nil {
- t.Logf("Error decoding: %v", err)
- t.FailNow()
- }
- if !reflect.DeepEqual(decoded, toEncode) {
- t.Logf("Decoded value %#v != %#v", decoded, toEncode)
- t.FailNow()
- }
- }
- func doTestEmbeddedFieldPrecedence(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- type Embedded struct {
- Field byte
- }
- type Struct struct {
- Field byte
- Embedded
- }
- toEncode := Struct{
- Field: 1,
- Embedded: Embedded{Field: 2},
- }
- _, isJsonHandle := h.(*JsonHandle)
- handle := basicHandle(h)
- oldMapType := handle.MapType
- defer func() { handle.MapType = oldMapType }()
- handle.MapType = reflect.TypeOf(map[interface{}]interface{}(nil))
- bs, err := testMarshal(toEncode, h)
- if err != nil {
- t.Logf("Error encoding: %v, Err: %v", toEncode, err)
- t.FailNow()
- }
- var decoded Struct
- err = testUnmarshal(&decoded, bs, h)
- if err != nil {
- t.Logf("Error decoding: %v", err)
- t.FailNow()
- }
- if decoded.Field != toEncode.Field {
- t.Logf("Decoded result %v != %v", decoded.Field, toEncode.Field) // hex to look at what was encoded
- if isJsonHandle {
- t.Logf("JSON encoded as: %s", bs) // hex to look at what was encoded
- }
- t.FailNow()
- }
- }
- func doTestLargeContainerLen(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- m := make(map[int][]struct{})
- for i := range []int{
- 0, 1,
- math.MaxInt8, math.MaxInt8 + 4, math.MaxInt8 - 4,
- math.MaxInt16, math.MaxInt16 + 4, math.MaxInt16 - 4,
- math.MaxInt32, math.MaxInt32 - 4,
- // math.MaxInt32 + 4, // bombs on 32-bit
- // math.MaxInt64, math.MaxInt64 - 4, // bombs on 32-bit
- math.MaxUint8, math.MaxUint8 + 4, math.MaxUint8 - 4,
- math.MaxUint16, math.MaxUint16 + 4, math.MaxUint16 - 4,
- // math.MaxUint32, math.MaxUint32 + 4, math.MaxUint32 - 4, // bombs on 32-bit
- } {
- m[i] = make([]struct{}, i)
- }
- bs := testMarshalErr(m, h, t, "-")
- var m2 = make(map[int][]struct{})
- testUnmarshalErr(m2, bs, h, t, "-")
- testDeepEqualErr(m, m2, t, "-")
- // do same tests for large strings (encoded as symbols or not)
- // skip if 32-bit or not using unsafe mode
- if safeMode || (32<<(^uint(0)>>63)) < 64 {
- return
- }
- // now, want to do tests for large strings, which
- // could be encoded as symbols.
- // to do this, we create a simple one-field struct,
- // use use flags to switch from symbols to non-symbols
- hbinc, okbinc := h.(*BincHandle)
- if okbinc {
- oldAsSymbols := hbinc.AsSymbols
- defer func() { hbinc.AsSymbols = oldAsSymbols }()
- }
- var out []byte = make([]byte, 0, math.MaxUint16*3/2)
- var in []byte = make([]byte, math.MaxUint16*3/2)
- for i := range in {
- in[i] = 'A'
- }
- e := NewEncoder(nil, h)
- for _, i := range []int{
- 0, 1, 4, 8, 12, 16, 28, 32, 36,
- math.MaxInt8, math.MaxInt8 + 4, math.MaxInt8 - 4,
- math.MaxInt16, math.MaxInt16 + 4, math.MaxInt16 - 4,
- math.MaxUint8, math.MaxUint8 + 4, math.MaxUint8 - 4,
- math.MaxUint16, math.MaxUint16 + 4, math.MaxUint16 - 4,
- } {
- var m1, m2 map[string]bool
- m1 = make(map[string]bool, 1)
- var s1 = stringView(in[:i])
- // fmt.Printf("testcontainerlen: large string: i: %v, |%s|\n", i, s1)
- m1[s1] = true
- if okbinc {
- hbinc.AsSymbols = 2
- }
- out = out[:0]
- e.ResetBytes(&out)
- e.MustEncode(m1)
- // bs, _ = testMarshalErr(m1, h, t, "-")
- m2 = make(map[string]bool, 1)
- testUnmarshalErr(m2, out, h, t, "no-symbols")
- testDeepEqualErr(m1, m2, t, "no-symbols")
- if okbinc {
- // now, do as symbols
- hbinc.AsSymbols = 1
- out = out[:0]
- e.ResetBytes(&out)
- e.MustEncode(m1)
- // bs, _ = testMarshalErr(m1, h, t, "-")
- m2 = make(map[string]bool, 1)
- testUnmarshalErr(m2, out, h, t, "symbols")
- testDeepEqualErr(m1, m2, t, "symbols")
- }
- }
- }
- func testRandomFillRV(v reflect.Value) {
- testOnce.Do(testInitAll)
- fneg := func() int64 {
- i := rand.Intn(1)
- if i == 1 {
- return 1
- }
- return -1
- }
- switch v.Kind() {
- case reflect.Invalid:
- case reflect.Ptr:
- if v.IsNil() {
- v.Set(reflect.New(v.Type().Elem()))
- }
- testRandomFillRV(v.Elem())
- case reflect.Interface:
- if v.IsNil() {
- v.Set(rv4i("nothing"))
- } else {
- testRandomFillRV(v.Elem())
- }
- case reflect.Struct:
- for i, n := 0, v.NumField(); i < n; i++ {
- testRandomFillRV(v.Field(i))
- }
- case reflect.Slice:
- if v.IsNil() {
- v.Set(reflect.MakeSlice(v.Type(), 4, 4))
- }
- fallthrough
- case reflect.Array:
- for i, n := 0, v.Len(); i < n; i++ {
- testRandomFillRV(v.Index(i))
- }
- case reflect.Map:
- if v.IsNil() {
- v.Set(reflect.MakeMap(v.Type()))
- }
- if v.Len() == 0 {
- kt, vt := v.Type().Key(), v.Type().Elem()
- for i := 0; i < 4; i++ {
- k0 := reflect.New(kt).Elem()
- v0 := reflect.New(vt).Elem()
- testRandomFillRV(k0)
- testRandomFillRV(v0)
- v.SetMapIndex(k0, v0)
- }
- } else {
- for _, k := range v.MapKeys() {
- testRandomFillRV(v.MapIndex(k))
- }
- }
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- v.SetInt(fneg() * rand.Int63n(127))
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- v.SetUint(uint64(rand.Int63n(255)))
- case reflect.Bool:
- v.SetBool(fneg() == 1)
- case reflect.Float32, reflect.Float64:
- v.SetFloat(float64(fneg()) * float64(rand.Float32()))
- case reflect.String:
- // ensure this string can test the extent of json string decoding
- v.SetString(strings.Repeat(strconv.FormatInt(rand.Int63n(99), 10), rand.Intn(8)) +
- "- ABC \x41=\x42 \u2318 - \r \b \f - \u2028 and \u2029 .")
- default:
- panic(fmt.Errorf("testRandomFillRV: unsupported type: %v", v.Kind()))
- }
- }
- func testMammoth(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- name := h.Name()
- var b []byte
- var m, m2 TestMammoth
- testRandomFillRV(rv4i(&m).Elem())
- b = testMarshalErr(&m, h, t, "mammoth-"+name)
- // xdebugf("%s", b)
- testUnmarshalErr(&m2, b, h, t, "mammoth-"+name)
- testDeepEqualErr(&m, &m2, t, "mammoth-"+name)
- var mm, mm2 TestMammoth2Wrapper
- testRandomFillRV(rv4i(&mm).Elem())
- b = testMarshalErr(&mm, h, t, "mammoth2-"+name)
- // os.Stderr.Write([]byte("\n\n\n\n" + string(b) + "\n\n\n\n"))
- testUnmarshalErr(&mm2, b, h, t, "mammoth2-"+name)
- testDeepEqualErr(&mm, &mm2, t, "mammoth2-"+name)
- // testMammoth2(t, name, h)
- }
- func testTime(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- name := h.Name()
- // test time which uses the time.go implementation (ie Binc)
- var tt, tt2 time.Time
- // time in 1990
- tt = time.Unix(20*366*24*60*60, 1000*900).In(time.FixedZone("UGO", -5*60*60))
- // fmt.Printf("time tt: %v\n", tt)
- b := testMarshalErr(tt, h, t, "time-"+name)
- testUnmarshalErr(&tt2, b, h, t, "time-"+name)
- // per go documentation, test time with .Equal not ==
- if !tt2.Equal(tt) {
- t.Logf("%s: values not equal: 1: %v, 2: %v", name, tt2, tt)
- t.FailNow()
- }
- // testDeepEqualErr(tt.UTC(), tt2, t, "time-"+name)
- }
- func testUintToInt(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- name := h.Name()
- var golden = [...]int64{
- 0, 1, 22, 333, 4444, 55555, 666666,
- // msgpack ones
- 24, 128,
- // standard ones
- math.MaxUint8, math.MaxUint8 + 4, math.MaxUint8 - 4,
- math.MaxUint16, math.MaxUint16 + 4, math.MaxUint16 - 4,
- math.MaxUint32, math.MaxUint32 + 4, math.MaxUint32 - 4,
- math.MaxInt8, math.MaxInt8 + 4, math.MaxInt8 - 4,
- math.MaxInt16, math.MaxInt16 + 4, math.MaxInt16 - 4,
- math.MaxInt32, math.MaxInt32 + 4, math.MaxInt32 - 4,
- math.MaxInt64, math.MaxInt64 - 4,
- }
- var i int64
- var ui, ui2 uint64
- var fi float64
- var b []byte
- for _, v := range golden {
- i = v
- ui = 0
- b = testMarshalErr(i, h, t, "int2uint-"+name)
- testUnmarshalErr(&ui, b, h, t, "int2uint-"+name)
- if ui != uint64(i) {
- t.Logf("%s: values not equal: %v, %v", name, ui, uint64(i))
- t.FailNow()
- }
- ui = uint64(i)
- i = 0
- b = testMarshalErr(ui, h, t, "uint2int-"+name)
- testUnmarshalErr(&i, b, h, t, "uint2int-"+name)
- if i != int64(ui) {
- t.Logf("%s: values not equal: %v, %v", name, i, int64(ui))
- t.FailNow()
- }
- if v == math.MaxInt64 {
- ui = uint64(-(v - 1))
- } else {
- ui = uint64(-v)
- }
- // xdebugf("testing %x", ui)
- b = testMarshalErr(ui, h, t, "negint2uint-"+name)
- testUnmarshalErr(&ui2, b, h, t, "negint2uint-"+name)
- if ui2 != ui {
- t.Logf("%s: values not equal: %v, %v", name, ui2, ui)
- t.FailNow()
- }
- fi = 0
- b = testMarshalErr(i, h, t, "int2float-"+name)
- testUnmarshalErr(&fi, b, h, t, "int2float-"+name)
- if fi != float64(i) {
- t.Logf("%s: values not equal: %v, %v", name, fi, float64(i))
- t.FailNow()
- }
- }
- }
- func doTestDifferentMapOrSliceType(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- name := h.Name()
- // - maptype, slicetype: diff from map[string]intf, map[intf]intf or []intf, etc
- // include map[interface{}]string where some keys are []byte.
- // To test, take a sequence of []byte and string, and decode into []string and []interface.
- // Also, decode into map[string]string, map[string]interface{}, map[interface{}]string
- bh := basicHandle(h)
- oldM, oldS := bh.MapType, bh.SliceType
- defer func() { bh.MapType, bh.SliceType = oldM, oldS }()
- var b []byte
- var vi = []interface{}{
- "hello 1",
- []byte("hello 2"),
- "hello 3",
- []byte("hello 4"),
- "hello 5",
- }
- var vs []string
- var v2i, v2s testMbsT
- var v2ss testMbsCustStrT
- // encode it as a map or as a slice
- for i, v := range vi {
- vv, ok := v.(string)
- if !ok {
- vv = string(v.([]byte))
- }
- vs = append(vs, vv)
- v2i = append(v2i, v, strconv.FormatInt(int64(i+1), 10))
- v2s = append(v2s, vv, strconv.FormatInt(int64(i+1), 10))
- v2ss = append(v2ss, testCustomStringT(vv), testCustomStringT(strconv.FormatInt(int64(i+1), 10)))
- }
- var v2d interface{}
- // encode vs as a list, and decode into a list and compare
- var goldSliceS = []string{"hello 1", "hello 2", "hello 3", "hello 4", "hello 5"}
- var goldSliceI = []interface{}{"hello 1", "hello 2", "hello 3", "hello 4", "hello 5"}
- var goldSlice = []interface{}{goldSliceS, goldSliceI}
- for j, g := range goldSlice {
- bh.SliceType = reflect.TypeOf(g)
- name := fmt.Sprintf("slice-%s-%v", name, j+1)
- b = testMarshalErr(vs, h, t, name)
- v2d = nil
- // v2d = reflect.New(bh.SliceType).Elem().Interface()
- testUnmarshalErr(&v2d, b, h, t, name)
- testDeepEqualErr(v2d, goldSlice[j], t, name)
- }
- // to ensure that we do not use fast-path for map[intf]string, use a custom string type (for goldMapIS).
- // this will allow us to test out the path that sees a []byte where a map has an interface{} type,
- // and convert it to a string for the decoded map key.
- // encode v2i as a map, and decode into a map and compare
- var goldMapSS = map[string]string{"hello 1": "1", "hello 2": "2", "hello 3": "3", "hello 4": "4", "hello 5": "5"}
- var goldMapSI = map[string]interface{}{"hello 1": "1", "hello 2": "2", "hello 3": "3", "hello 4": "4", "hello 5": "5"}
- var goldMapIS = map[interface{}]testCustomStringT{"hello 1": "1", "hello 2": "2", "hello 3": "3", "hello 4": "4", "hello 5": "5"}
- var goldMap = []interface{}{goldMapSS, goldMapSI, goldMapIS}
- for j, g := range goldMap {
- bh.MapType = reflect.TypeOf(g)
- name := fmt.Sprintf("map-%s-%v", name, j+1)
- // for formats that clearly differentiate binary from string, use v2i
- // else use the v2s (with all strings, no []byte)
- v2d = nil
- // v2d = reflect.New(bh.MapType).Elem().Interface()
- switch h.(type) {
- case *MsgpackHandle, *BincHandle, *CborHandle:
- b = testMarshalErr(v2i, h, t, name)
- testUnmarshalErr(&v2d, b, h, t, name)
- testDeepEqualErr(v2d, goldMap[j], t, name)
- default:
- b = testMarshalErr(v2s, h, t, name)
- testUnmarshalErr(&v2d, b, h, t, name)
- testDeepEqualErr(v2d, goldMap[j], t, name)
- b = testMarshalErr(v2ss, h, t, name)
- v2d = nil
- testUnmarshalErr(&v2d, b, h, t, name)
- testDeepEqualErr(v2d, goldMap[j], t, name)
- }
- }
- }
- func doTestScalars(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- // for each scalar:
- // - encode its ptr
- // - encode it (non-ptr)
- // - check that bytes are same
- // - make a copy (using reflect)
- // - check that same
- // - set zero on it
- // - check that its equal to 0 value
- // - decode into new
- // - compare to original
- bh := basicHandle(h)
- if !bh.Canonical {
- bh.Canonical = true
- defer func() { bh.Canonical = false }()
- }
- vi := []interface{}{
- int(0),
- int8(0),
- int16(0),
- int32(0),
- int64(0),
- uint(0),
- uint8(0),
- uint16(0),
- uint32(0),
- uint64(0),
- uintptr(0),
- float32(0),
- float64(0),
- bool(false),
- string(""),
- []byte(nil),
- }
- for _, v := range fastpathAV {
- vi = append(vi, reflect.Zero(v.rt).Interface())
- }
- for _, v := range vi {
- rv := reflect.New(reflect.TypeOf(v)).Elem()
- testRandomFillRV(rv)
- v = rv.Interface()
- rv2 := reflect.New(rv.Type())
- rv2.Elem().Set(rv)
- vp := rv2.Interface()
- var tname string
- switch rv.Kind() {
- case reflect.Map:
- tname = "map[" + rv.Type().Key().Name() + "]" + rv.Type().Elem().Name()
- case reflect.Slice:
- tname = "[]" + rv.Type().Elem().Name()
- default:
- tname = rv.Type().Name()
- }
- var b, b1, b2 []byte
- b1 = testMarshalErr(v, h, t, tname+"-enc")
- // store b1 into b, as b1 slice is reused for next marshal
- b = make([]byte, len(b1))
- copy(b, b1)
- b2 = testMarshalErr(vp, h, t, tname+"-enc-ptr")
- testDeepEqualErr(b1, b2, t, tname+"-enc-eq")
- setZero(vp)
- testDeepEqualErr(rv2.Elem().Interface(), reflect.Zero(rv.Type()).Interface(), t, tname+"-enc-eq-zero-ref")
- vp = rv2.Interface()
- testUnmarshalErr(vp, b, h, t, tname+"-dec")
- testDeepEqualErr(rv2.Elem().Interface(), v, t, tname+"-dec-eq")
- }
- }
- func doTestIntfMapping(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- name := h.Name()
- rti := reflect.TypeOf((*testIntfMapI)(nil)).Elem()
- defer func() { basicHandle(h).Intf2Impl(rti, nil) }()
- type T9 struct {
- I testIntfMapI
- }
- for i, v := range []testIntfMapI{
- // Use a valid string to test some extents of json string decoding
- &testIntfMapT1{"ABC \x41=\x42 \u2318 - \r \b \f - \u2028 and \u2029 ."},
- testIntfMapT2{"DEF"},
- } {
- if err := basicHandle(h).Intf2Impl(rti, reflect.TypeOf(v)); err != nil {
- t.Logf("Error mapping %v to %T", rti, v)
- t.FailNow()
- }
- var v1, v2 T9
- v1 = T9{v}
- b := testMarshalErr(v1, h, t, name+"-enc-"+strconv.Itoa(i))
- testUnmarshalErr(&v2, b, h, t, name+"-dec-"+strconv.Itoa(i))
- testDeepEqualErr(v1, v2, t, name+"-dec-eq-"+strconv.Itoa(i))
- }
- }
- func doTestOmitempty(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- name := h.Name()
- if basicHandle(h).StructToArray {
- t.Skipf("Skipping OmitEmpty test when StructToArray=true")
- }
- type T1 struct {
- A int `codec:"a"`
- B *int `codec:"b,omitempty"`
- C int `codec:"c,omitempty"`
- }
- type T2 struct {
- A int `codec:"a"`
- }
- var v1 T1
- var v2 T2
- b1 := testMarshalErr(v1, h, t, name+"-omitempty")
- b2 := testMarshalErr(v2, h, t, name+"-no-omitempty-trunc")
- testDeepEqualErr(b1, b2, t, name+"-omitempty-cmp")
- }
- func doTestMissingFields(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- name := h.Name()
- if codecgen {
- t.Skipf("Skipping Missing Fields tests as it is not honored by codecgen")
- }
- if basicHandle(h).StructToArray {
- t.Skipf("Skipping Missing Fields test when StructToArray=true")
- }
- // encode missingFielderT2, decode into missingFielderT1, encode it out again, decode into new missingFielderT2, compare
- v1 := missingFielderT2{S: "true seven eight", B: true, F: 777.0, I: -888}
- b1 := testMarshalErr(v1, h, t, name+"-missing-enc-2")
- // xdebugf("marshal into b1: %s", b1)
- var v2 missingFielderT1
- testUnmarshalErr(&v2, b1, h, t, name+"-missing-dec-1")
- // xdebugf("unmarshal into v2: %v", v2)
- b2 := testMarshalErr(&v2, h, t, name+"-missing-enc-1")
- // xdebugf("marshal into b2: %s", b2)
- var v3 missingFielderT2
- testUnmarshalErr(&v3, b2, h, t, name+"-missing-dec-2")
- // xdebugf("unmarshal into v3: %v", v3)
- testDeepEqualErr(v1, v3, t, name+"-missing-cmp-2")
- }
- func doTestMaxDepth(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- name := h.Name()
- type T struct {
- I interface{} // value to encode
- M int16 // maxdepth
- S bool // use swallow (decode into typed struct with only A1)
- E interface{} // error to find
- }
- type T1 struct {
- A1 *T1
- }
- var table []T
- var sfunc = func(n int) (s [1]interface{}, s1 *[1]interface{}) {
- s1 = &s
- for i := 0; i < n; i++ {
- var s0 [1]interface{}
- s1[0] = &s0
- s1 = &s0
- }
- // xdebugf("sfunc s: %v", s)
- return
- // var s []interface{}
- // s = append(s, []interface{})
- // s[0] = append(s[0], []interface{})
- // s[0][0] = append(s[0][0], []interface{})
- // s[0][0][0] = append(s[0][0][0], []interface{})
- // s[0][0][0][0] = append(s[0][0][0][0], []interface{})
- // return s
- }
- var mfunc = func(n int) (m map[string]interface{}, mlast map[string]interface{}) {
- m = make(map[string]interface{})
- mlast = make(map[string]interface{})
- m["A0"] = mlast
- for i := 1; i < n; i++ {
- m0 := make(map[string]interface{})
- mlast["A"+strconv.FormatInt(int64(i), 10)] = m0
- mlast = m0
- }
- // xdebugf("mfunc m: %v", m)
- return
- }
- s, s1 := sfunc(5)
- m, _ := mfunc(5)
- m99, _ := mfunc(99)
- s1[0] = m
- table = append(table, T{s, 0, false, nil})
- table = append(table, T{s, 256, false, nil})
- table = append(table, T{s, 7, false, errMaxDepthExceeded})
- table = append(table, T{s, 15, false, nil})
- table = append(table, T{m99, 15, true, errMaxDepthExceeded})
- table = append(table, T{m99, 215, true, nil})
- defer func(n int16, b bool) {
- basicHandle(h).MaxDepth = n
- testUseMust = b
- }(basicHandle(h).MaxDepth, testUseMust)
- testUseMust = false
- for i, v := range table {
- basicHandle(h).MaxDepth = v.M
- b1 := testMarshalErr(v.I, h, t, name+"-maxdepth-enc"+strconv.FormatInt(int64(i), 10))
- // xdebugf("b1: %s", b1)
- var err error
- if v.S {
- var v2 T1
- err = testUnmarshal(&v2, b1, h)
- } else {
- var v2 interface{}
- err = testUnmarshal(&v2, b1, h)
- }
- if err1, ok := err.(decodeError); ok {
- err = err1.codecError
- }
- var err0 interface{} = err
- if err1, ok := err.(codecError); ok {
- err0 = err1.err
- }
- if err0 != v.E {
- t.Logf("Unexpected error testing max depth for depth %d: expected %v, received %v", v.M, v.E, err)
- t.FailNow()
- }
- // decode into something that just triggers swallow
- }
- }
- func doTestMultipleEncDec(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- name := h.Name()
- // encode a string multiple times.
- // decode it multiple times.
- // ensure we get the value each time
- var s1 = "ugorji"
- var s2 = "nwoke"
- var s11, s21 string
- var buf bytes.Buffer
- e := NewEncoder(&buf, h)
- e.MustEncode(s1)
- e.MustEncode(s2)
- d := NewDecoder(&buf, h)
- d.MustDecode(&s11)
- d.MustDecode(&s21)
- testDeepEqualErr(s1, s11, t, name+"-multiple-encode")
- testDeepEqualErr(s2, s21, t, name+"-multiple-encode")
- }
- func doTestSelfExt(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- name := h.Name()
- var ts TestSelfExtImpl
- ts.S = "ugorji"
- ts.I = 5678
- ts.B = true
- var ts2 TestSelfExtImpl
- bs := testMarshalErr(&ts, h, t, name)
- testUnmarshalErr(&ts2, bs, h, t, name)
- testDeepEqualErr(&ts, &ts2, t, name)
- }
- func doTestBytesEncodedAsArray(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- name := h.Name()
- // Need to test edge case where bytes are encoded as an array
- // (not using optimized []byte native format)
- // encode []int8 (or int32 or any numeric type) with all positive numbers
- // decode it into []uint8
- var in = make([]int32, 128)
- var un = make([]uint8, 128)
- for i := range in {
- in[i] = int32(i)
- un[i] = uint8(i)
- }
- var out []byte
- bs := testMarshalErr(&in, h, t, name)
- testUnmarshalErr(&out, bs, h, t, name)
- // xdebugf("in: %v", in)
- // xdebug2f("out: %v\n", out)
- testDeepEqualErr(un, out, t, name)
- }
- func doTestStrucEncDec(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- name := h.Name()
- {
- var ts1 = newTestStruc(2, testNumRepeatString, false, !testSkipIntf, testMapStringKeyOnly)
- var ts2 TestStruc
- bs := testMarshalErr(ts1, h, t, name)
- testUnmarshalErr(&ts2, bs, h, t, name)
- testDeepEqualErr(ts1, &ts2, t, name)
- }
- // Note: We cannot use TestStrucFlex because it has omitempty values,
- // Meaning that sometimes, encoded and decoded will not be same.
- // {
- // var ts1 = newTestStrucFlex(2, testNumRepeatString, false, !testSkipIntf, testMapStringKeyOnly)
- // var ts2 TestStrucFlex
- // bs := testMarshalErr(ts1, h, t, name)
- // fmt.Printf("\n\n%s\n\n", bs)
- // testUnmarshalErr(&ts2, bs, h, t, name)
- // testDeepEqualErr(ts1, &ts2, t, name)
- // }
- }
- func doTestStructKeyType(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- name := h.Name()
- mh, mok := h.(*MsgpackHandle)
- bch, bcok := h.(*BincHandle)
- bh := basicHandle(h)
- s2a := bh.StructToArray
- bh.StructToArray = false
- var mfx bool
- if mok {
- mfx = mh.NoFixedNum
- mh.NoFixedNum = false
- }
- var bcsym uint8
- if bcok {
- bcsym = bch.AsSymbols
- bch.AsSymbols = 2 // TODO: should be 0 but binc symbols do not work well
- }
- defer func() {
- bh.StructToArray = s2a
- if mok {
- mh.NoFixedNum = mfx
- }
- if bcok {
- bch.AsSymbols = bcsym
- }
- }()
- var bs1, bs2 []byte
- var m = make(map[interface{}]interface{})
- fn := func(v interface{}) {
- bs1 = testMarshalErr(v, h, t, "")
- bs2 = testMarshalErr(m, h, t, "")
- // if _, ok := h.(*JsonHandle); ok {
- // xdebugf("bs1: %s, bs2: %s", bs1, bs2)
- // }
- // if bcok {
- // xdebug2f("-------------")
- // xdebugf("v: %#v, m: %#v", v, m)
- // xdebugf("bs1: %v", bs1)
- // xdebugf("bs2: %v", bs2)
- // xdebugf("bs1==bs2: %v", bytes.Equal(bs1, bs2))
- // testDeepEqualErr(bs1, bs2, t, name+"")
- // xdebug2f("-------------")
- // return
- // }
- testDeepEqualErr(bs1, bs2, t, name+"")
- }
- fnclr := func() {
- for k := range m {
- delete(m, k)
- }
- }
- m["F"] = 0
- fn(testStrucKeyTypeT0{})
- fnclr()
- m["FFFF"] = 0
- fn(testStrucKeyTypeT1{})
- fnclr()
- m[int64(-1)] = 0
- fn(testStrucKeyTypeT2{})
- fnclr()
- m[int64(1)] = 0
- fn(testStrucKeyTypeT3{})
- fnclr()
- m[float64(2.5)] = 0
- fn(testStrucKeyTypeT4{})
- fnclr()
- }
- func doTestRawToStringToRawEtc(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- // name := h.Name()
- // Tests:
- // - RawToString
- // - StringToRaw
- // - MapValueReset
- // - DeleteOnMapValue (skipped - no longer supported)
- bh := basicHandle(h)
- // xdebugf("[%s] maptype: %v, slice type: %v", name, bh.MapType, bh.SliceType)
- r2s := bh.RawToString
- s2r := bh.StringToRaw
- can := bh.Canonical
- mvr := bh.MapValueReset
- var wext bool
- mh, mok := h.(*MsgpackHandle)
- if mok {
- wext = mh.WriteExt
- }
- _, jok := h.(*JsonHandle)
- defer func() {
- bh.RawToString = r2s
- bh.StringToRaw = s2r
- bh.Canonical = can
- bh.MapValueReset = mvr
- if mok {
- mh.WriteExt = wext
- }
- }()
- bh.Canonical = false
- var bs1, bs2 []byte
- // encode: StringToRaw
- // decode: RawToString
- // compare encoded v1 to encoded v2, while setting StringToRaw to b
- fne := func(v1, v2 interface{}, b bool) {
- // xdebugf("[%s] fne: StringToRaw: %v, v1: %#v, v2: %#v", name, b, v1, v2)
- bh.StringToRaw = b
- bs1 = testMarshalErr(v1, h, t, "")
- // bs1 = []byte(string(bs1))
- bs2 = testMarshalErr(v2, h, t, "")
- // if jok {
- // xdebugf("[%s] fne: bh: %#v", name, bh.EncodeOptions)
- // xdebugf("[%s] bs1: %s", name, bs1)
- // xdebugf("[%s] bs2: %s", name, bs2)
- // }
- testDeepEqualErr(bs1, bs2, t, "")
- }
- // encoded v1, decode naked and compare to v2
- fnd := func(v1, v2 interface{}, bs2r, br2s, bwext bool) {
- bh.RawToString = br2s
- bh.StringToRaw = bs2r
- if mok {
- mh.WriteExt = bwext
- }
- bs1 = testMarshalErr(v1, h, t, "")
- var vn interface{}
- testUnmarshalErr(&vn, bs1, h, t, "")
- testDeepEqualErr(vn, v2, t, "")
- }
- sv0 := "value"
- bv0 := []byte(sv0)
- sv1 := sv0
- bv1 := []byte(sv1)
- m1 := map[string]*string{"key": &sv1}
- m2 := map[string]*[]byte{"key": &bv1}
- // m3 := map[[3]byte]string{[3]byte{'k', 'e', 'y'}: sv0}
- m4 := map[[3]byte][]byte{[3]byte{'k', 'e', 'y'}: bv0}
- m5 := map[string][]byte{"key": bv0}
- // m6 := map[string]string{"key": sv0}
- m7 := map[interface{}]interface{}{"key": sv0}
- m8 := map[interface{}]interface{}{"key": bv0}
- // StringToRaw=true
- fne(m1, m4, true)
- // StringToRaw=false
- // compare encoded m2 to encoded m5
- fne(m2, m5, false)
- // json doesn't work well with StringToRaw and RawToString
- // when dealing with interfaces, because it cannot decipher
- // that a string should be treated as base64.
- if jok {
- goto MAP_VALUE_RESET
- }
- // if msgpack, always set WriteExt = RawToString
- // StringToRaw=true (RawToString=true)
- // encoded m1, decode naked and compare to m5
- fnd(m2, m7, true, true, true)
- // StringToRaw=true (RawToString=false)
- // encoded m1, decode naked and compare to m6
- fnd(m1, m8, true, false, false)
- // StringToRaw=false, RawToString=true
- // encode m1, decode naked, and compare to m6
- fnd(m2, m7, false, true, true)
- MAP_VALUE_RESET:
- // set MapValueReset, and then decode i
- sv2 := "value-new"
- m9 := map[string]*string{"key": &sv2}
- bs1 = testMarshalErr(m1, h, t, "")
- bh.MapValueReset = false
- testUnmarshalErr(&m9, bs1, h, t, "")
- // if !(m9["key"] == m1["key"]
- testDeepEqualErr(sv2, "value", t, "")
- testDeepEqualErr(&sv2, m9["key"], t, "")
- sv2 = "value-new"
- m9["key"] = &sv2
- bh.MapValueReset = true
- testUnmarshalErr(&m9, bs1, h, t, "")
- testDeepEqualErr(sv2, "value-new", t, "")
- testDeepEqualErr("value", *(m9["key"]), t, "")
- // t1 = struct {
- // key string
- // }{ key: sv0 }
- // t2 := struct {
- // key []byte
- // }{ key: bv1 }
- }
- // -----------------
- func TestJsonDecodeNonStringScalarInStringContext(t *testing.T) {
- testOnce.Do(testInitAll)
- var b = `{"s.true": "true", "b.true": true, "s.false": "false", "b.false": false, "s.10": "10", "i.10": 10, "i.-10": -10}`
- var golden = map[string]string{"s.true": "true", "b.true": "true", "s.false": "false", "b.false": "false", "s.10": "10", "i.10": "10", "i.-10": "-10"}
- var m map[string]string
- d := NewDecoderBytes([]byte(b), testJsonH)
- d.MustDecode(&m)
- if err := deepEqual(golden, m); err == nil {
- if testVerbose {
- t.Logf("++++ match: decoded: %#v", m)
- }
- } else {
- t.Logf("---- mismatch: %v ==> golden: %#v, decoded: %#v", err, golden, m)
- t.FailNow()
- }
- }
- func TestJsonEncodeIndent(t *testing.T) {
- testOnce.Do(testInitAll)
- v := TestSimplish{
- Ii: -794,
- Ss: `A Man is
- after the new line
- after new line and tab
- `,
- }
- v2 := v
- v.Mm = make(map[string]*TestSimplish)
- for i := 0; i < len(v.Ar); i++ {
- v3 := v2
- v3.Ii += (i * 4)
- v3.Ss = fmt.Sprintf("%d - %s", v3.Ii, v3.Ss)
- if i%2 == 0 {
- v.Ar[i] = &v3
- }
- // v3 = v2
- v.Sl = append(v.Sl, &v3)
- v.Mm[strconv.FormatInt(int64(i), 10)] = &v3
- }
- oldcan := testJsonH.Canonical
- oldIndent := testJsonH.Indent
- oldS2A := testJsonH.StructToArray
- defer func() {
- testJsonH.Canonical = oldcan
- testJsonH.Indent = oldIndent
- testJsonH.StructToArray = oldS2A
- }()
- testJsonH.Canonical = true
- testJsonH.Indent = -1
- testJsonH.StructToArray = false
- var bs []byte
- NewEncoderBytes(&bs, testJsonH).MustEncode(&v)
- txt1Tab := string(bs)
- bs = nil
- testJsonH.Indent = 120
- NewEncoderBytes(&bs, testJsonH).MustEncode(&v)
- txtSpaces := string(bs)
- // fmt.Printf("\n-----------\n%s\n------------\n%s\n-------------\n", txt1Tab, txtSpaces)
- goldenResultTab := `{
- "Ar": [
- {
- "Ar": [
- null,
- null
- ],
- "Ii": -794,
- "Mm": null,
- "Sl": null,
- "Ss": "-794 - A Man is\nafter the new line\n\tafter new line and tab\n"
- },
- null
- ],
- "Ii": -794,
- "Mm": {
- "0": {
- "Ar": [
- null,
- null
- ],
- "Ii": -794,
- "Mm": null,
- "Sl": null,
- "Ss": "-794 - A Man is\nafter the new line\n\tafter new line and tab\n"
- },
- "1": {
- "Ar": [
- null,
- null
- ],
- "Ii": -790,
- "Mm": null,
- "Sl": null,
- "Ss": "-790 - A Man is\nafter the new line\n\tafter new line and tab\n"
- }
- },
- "Sl": [
- {
- "Ar": [
- null,
- null
- ],
- "Ii": -794,
- "Mm": null,
- "Sl": null,
- "Ss": "-794 - A Man is\nafter the new line\n\tafter new line and tab\n"
- },
- {
- "Ar": [
- null,
- null
- ],
- "Ii": -790,
- "Mm": null,
- "Sl": null,
- "Ss": "-790 - A Man is\nafter the new line\n\tafter new line and tab\n"
- }
- ],
- "Ss": "A Man is\nafter the new line\n\tafter new line and tab\n"
- }`
- if txt1Tab != goldenResultTab {
- t.Logf("decoded indented with tabs != expected: \nexpected: %s\nencoded: %s", goldenResultTab, txt1Tab)
- t.FailNow()
- }
- if txtSpaces != strings.Replace(goldenResultTab, "\t", strings.Repeat(" ", 120), -1) {
- t.Logf("decoded indented with spaces != expected: \nexpected: %s\nencoded: %s", goldenResultTab, txtSpaces)
- t.FailNow()
- }
- }
- func doTestBufioDecReader(t *testing.T, bufsize int) {
- testOnce.Do(testInitAll)
- bufsizehalf := (bufsize + 1) / 2
- // TODO: add testing when the buffer size is smaller than the string length.
- // try to read 85 bytes in chunks of 7 at a time.
- var s = strings.Repeat("01234'56789 ", 5)
- // fmt.Printf("s: %s\n", s)
- var r = strings.NewReader(s)
- var br bufioDecReader
- var blist bytesFreelist
- br.reset(r, bufsize, &blist)
- b, err := ioutil.ReadAll(br.r)
- if err != nil {
- panic(err)
- }
- var s2 = string(b)
- // fmt.Printf("s==s2: %v, len(s): %v, len(b): %v, len(s2): %v\n", s == s2, len(s), len(b), len(s2))
- if s != s2 {
- t.Logf("not equal: \ns: %s\ns2: %s", s, s2)
- t.FailNow()
- }
- // Now, test search functions for skip, readTo and readUntil
- // readUntil ', readTo ', skip whitespace. 3 times in a loop, each time compare the token and/or outs
- // readUntil: see: 56789
- var out []byte
- var token byte
- br.reset(strings.NewReader(s), bufsizehalf, &blist)
- // println()
- for _, v2 := range [...]string{
- `01234'`,
- `56789 01234'`,
- `56789 01234'`,
- `56789 01234'`,
- } {
- out = br.readUntil('\'', true)
- testDeepEqualErr(string(out), v2, t, "-")
- // fmt.Printf("readUntil: out: `%s`\n", out)
- }
- br.reset(strings.NewReader(s), bufsizehalf, &blist)
- // println()
- for range [4]struct{}{} {
- out = br.readTo(&numCharBitset)
- testDeepEqualErr(string(out), `01234`, t, "-")
- // fmt.Printf("readTo: out: `%s`\n", out)
- out = br.readUntil('\'', true)
- testDeepEqualErr(string(out), "'", t, "-")
- // fmt.Printf("readUntil: out: `%s`\n", out)
- out = br.readTo(&numCharBitset)
- testDeepEqualErr(string(out), `56789`, t, "-")
- // fmt.Printf("readTo: out: `%s`\n", out)
- out = br.readUntil('0', true)
- testDeepEqualErr(string(out), ` 0`, t, "-")
- // fmt.Printf("readUntil: out: `%s`\n", out)
- br.unreadn1()
- }
- br.reset(strings.NewReader(s), bufsizehalf, &blist)
- // println()
- for range [4]struct{}{} {
- out = br.readUntil(' ', true)
- testDeepEqualErr(string(out), `01234'56789 `, t, "-")
- // fmt.Printf("readUntil: out: |%s|\n", out)
- token = br.skipWhitespace() // br.skip(&whitespaceCharBitset)
- testDeepEqualErr(token, byte('0'), t, "-")
- // fmt.Printf("skip: token: '%c'\n", token)
- br.unreadn1()
- }
- // println()
- }
- func doTestPreferArrayOverSlice(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- // encode a slice, decode it with PreferArrayOverSlice
- // if codecgen, skip the test (as codecgen doesn't work with PreferArrayOverSlice)
- if codecgen {
- t.Skip()
- }
- bh := basicHandle(h)
- paos := bh.PreferArrayOverSlice
- styp := bh.SliceType
- defer func() {
- bh.PreferArrayOverSlice = paos
- bh.SliceType = styp
- }()
- bh.PreferArrayOverSlice = true
- bh.SliceType = reflect.TypeOf(([]bool)(nil))
- s2 := [4]bool{true, false, true, false}
- s := s2[:]
- var v interface{}
- bs := testMarshalErr(s, h, t, t.Name())
- testUnmarshalErr(&v, bs, h, t, t.Name())
- testDeepEqualErr(s2, v, t, t.Name())
- }
- func doTestZeroCopyBytes(t *testing.T, h Handle) {
- testOnce.Do(testInitAll)
- // jsonhandle and cborhandle with indefiniteLength do not support inline bytes, so skip them.
- if _, ok := h.(*JsonHandle); ok { // if h == testJsonH {
- t.Skip()
- }
- if ch, ok := h.(*CborHandle); ok && ch.IndefiniteLength {
- t.Skip()
- }
- bh := basicHandle(h)
- zc := bh.ZeroCopy
- defer func() {
- bh.ZeroCopy = zc
- }()
- bh.ZeroCopy = true
- s := []byte("hello")
- var v []byte
- bs := testMarshalErr(s, h, t, t.Name())
- // Note: this test only works for decoding from []byte, so cannot use testUnmarshalErr
- NewDecoderBytes(bs, h).MustDecode(&v)
- // testUnmarshalErr(&v, bs, h, t, t.Name())
- // validate that bs and s points into the bs stream
- for i := range bs {
- if &bs[i] == &v[0] {
- return
- }
- }
- // if not match, then a failure happened.
- if len(bs) > 0 && len(v) > 0 {
- t.Logf("%s: ZeroCopy=true, but decoded (%p) is not slice of input: (%p)", h.Name(), &v[0], &bs[0])
- } else {
- t.Logf("%s: ZeroCopy=true, but decoded OR input slice is empty: %v, %v", h.Name(), v, bs)
- }
- t.FailNow()
- }
- func TestBufioDecReader(t *testing.T) {
- testOnce.Do(testInitAll)
- doTestBufioDecReader(t, 13)
- doTestBufioDecReader(t, 3)
- doTestBufioDecReader(t, 5)
- doTestBufioDecReader(t, 127)
- }
- func TestAtomic(t *testing.T) {
- testOnce.Do(testInitAll)
- // load, store, load, confirm
- if true {
- var a atomicTypeInfoSlice
- l := a.load()
- if l != nil {
- t.Logf("atomic fail: %T, expected load return nil, received: %v", a, l)
- t.FailNow()
- }
- l = append(l, rtid2ti{})
- a.store(l)
- l = a.load()
- if len(l) != 1 {
- t.Logf("atomic fail: %T, expected load to have length 1, received: %d", a, len(l))
- t.FailNow()
- }
- }
- if true {
- var a atomicRtidFnSlice
- l := a.load()
- if l != nil {
- t.Logf("atomic fail: %T, expected load return nil, received: %v", a, l)
- t.FailNow()
- }
- l = append(l, codecRtidFn{})
- a.store(l)
- l = a.load()
- if len(l) != 1 {
- t.Logf("atomic fail: %T, expected load to have length 1, received: %d", a, len(l))
- t.FailNow()
- }
- }
- if true {
- var a atomicClsErr
- l := a.load()
- if l.errClosed != nil {
- t.Logf("atomic fail: %T, expected load return clsErr = nil, received: %v", a, l.errClosed)
- t.FailNow()
- }
- l.errClosed = io.EOF
- a.store(l)
- l = a.load()
- if l.errClosed != io.EOF {
- t.Logf("atomic fail: %T, expected clsErr = io.EOF, received: %v", a, l.errClosed)
- t.FailNow()
- }
- }
- }
- // -----------
- func TestJsonLargeInteger(t *testing.T) {
- testOnce.Do(testInitAll)
- for _, i := range []uint8{'L', 'A', 0} {
- for _, j := range []interface{}{
- int64(1 << 60),
- -int64(1 << 60),
- 0,
- 1 << 20,
- -(1 << 20),
- uint64(1 << 60),
- uint(0),
- uint(1 << 20),
- } {
- doTestJsonLargeInteger(t, j, i)
- }
- }
- oldIAS := testJsonH.IntegerAsString
- defer func() { testJsonH.IntegerAsString = oldIAS }()
- testJsonH.IntegerAsString = 0
- type tt struct {
- s string
- canI, canUi bool
- i int64
- ui uint64
- }
- var i int64
- var ui uint64
- var err error
- var d *Decoder = NewDecoderBytes(nil, testJsonH)
- for _, v := range []tt{
- {"0", true, true, 0, 0},
- {"0000", true, true, 0, 0},
- {"0.00e+2", true, true, 0, 0},
- {"000e-2", true, true, 0, 0},
- {"0.00e-2", true, true, 0, 0},
- {"9223372036854775807", true, true, math.MaxInt64, math.MaxInt64}, // maxint64
- {"92233720368547758.07e+2", true, true, math.MaxInt64, math.MaxInt64}, // maxint64
- {"922337203685477580700e-2", true, true, math.MaxInt64, math.MaxInt64}, // maxint64
- {"9223372.036854775807E+12", true, true, math.MaxInt64, math.MaxInt64}, // maxint64
- {"9223372036854775807000000000000E-12", true, true, math.MaxInt64, math.MaxInt64}, // maxint64
- {"0.9223372036854775807E+19", true, true, math.MaxInt64, math.MaxInt64}, // maxint64
- {"92233720368547758070000000000000000000E-19", true, true, math.MaxInt64, math.MaxInt64}, // maxint64
- {"0.000009223372036854775807E+24", true, true, math.MaxInt64, math.MaxInt64}, // maxint64
- {"9223372036854775807000000000000000000000000E-24", true, true, math.MaxInt64, math.MaxInt64}, // maxint64
- {"-9223372036854775808", true, false, math.MinInt64, 0}, // minint64
- {"-92233720368547758.08e+2", true, false, math.MinInt64, 0}, // minint64
- {"-922337203685477580800E-2", true, false, math.MinInt64, 0}, // minint64
- {"-9223372.036854775808e+12", true, false, math.MinInt64, 0}, // minint64
- {"-9223372036854775808000000000000E-12", true, false, math.MinInt64, 0}, // minint64
- {"-0.9223372036854775808e+19", true, false, math.MinInt64, 0}, // minint64
- {"-92233720368547758080000000000000000000E-19", true, false, math.MinInt64, 0}, // minint64
- {"-0.000009223372036854775808e+24", true, false, math.MinInt64, 0}, // minint64
- {"-9223372036854775808000000000000000000000000E-24", true, false, math.MinInt64, 0}, // minint64
- {"18446744073709551615", false, true, 0, math.MaxUint64}, // maxuint64
- {"18446744.073709551615E+12", false, true, 0, math.MaxUint64}, // maxuint64
- {"18446744073709551615000000000000E-12", false, true, 0, math.MaxUint64}, // maxuint64
- {"0.000018446744073709551615E+24", false, true, 0, math.MaxUint64}, // maxuint64
- {"18446744073709551615000000000000000000000000E-24", false, true, 0, math.MaxUint64}, // maxuint64
- // Add test for limit of uint64 where last digit is 0
- {"18446744073709551610", false, true, 0, math.MaxUint64 - 5}, // maxuint64
- {"18446744.073709551610E+12", false, true, 0, math.MaxUint64 - 5}, // maxuint64
- {"18446744073709551610000000000000E-12", false, true, 0, math.MaxUint64 - 5}, // maxuint64
- {"0.000018446744073709551610E+24", false, true, 0, math.MaxUint64 - 5}, // maxuint64
- {"18446744073709551610000000000000000000000000E-24", false, true, 0, math.MaxUint64 - 5}, // maxuint64
- // {"", true, true},
- } {
- if v.s == "" {
- continue
- }
- if true {
- d.ResetBytes([]byte(v.s))
- err = d.Decode(&ui)
- if (v.canUi && err != nil) || (!v.canUi && err == nil) || (v.canUi && err == nil && v.ui != ui) {
- t.Logf("Failing to decode %s (as unsigned): %v", v.s, err)
- t.FailNow()
- }
- }
- if true {
- d.ResetBytes([]byte(v.s))
- err = d.Decode(&i)
- if (v.canI && err != nil) || (!v.canI && err == nil) || (v.canI && err == nil && v.i != i) {
- t.Logf("Failing to decode %s (as signed): %v", v.s, err)
- t.FailNow()
- }
- }
- }
- }
- func TestJsonInvalidUnicode(t *testing.T) {
- testOnce.Do(testInitAll)
- // t.Skipf("new json implementation does not handle bad unicode robustly")
- var m = map[string]string{
- `"\udc49\u0430abc"`: "\uFFFDabc",
- `"\udc49\u0430"`: "\uFFFD",
- `"\udc49abc"`: "\uFFFDabc",
- `"\udc49"`: "\uFFFD",
- `"\udZ49\u0430abc"`: "\uFFFD\u0430abc",
- `"\udcG9\u0430"`: "\uFFFD\u0430",
- `"\uHc49abc"`: "\uFFFDabc",
- `"\uKc49"`: "\uFFFD",
- }
- // set testUseMust to true, so we can capture errors
- if testUseMust {
- testUseMust = false
- defer func() { testUseMust = true }()
- }
- for k, v := range m {
- var s string
- // call testUnmarshal directly, so we can check for EOF
- //
- // testUnmarshalErr(&s, []byte(k), testJsonH, t, "-")
- err := testUnmarshal(&s, []byte(k), testJsonH)
- if err != nil {
- if err == io.EOF {
- continue
- }
- t.Logf("%s: unmarshal failed: %v", "-", err)
- t.FailNow()
- }
- if s != v {
- t.Logf("not equal: %q, %q", v, s)
- t.FailNow()
- }
- }
- }
- func TestMsgpackDecodeMapAndExtSizeMismatch(t *testing.T) {
- fn := func(t *testing.T, b []byte, v interface{}) {
- if err := NewDecoderBytes(b, testMsgpackH).Decode(v); err != io.EOF && err != io.ErrUnexpectedEOF {
- t.Fatalf("expected EOF or ErrUnexpectedEOF, got %v", err)
- }
- }
- // a map claiming to have 0x10eeeeee KV pairs, but only has 1.
- var b = []byte{0xdf, 0x10, 0xee, 0xee, 0xee, 0x1, 0xa1, 0x1}
- var m1 map[int]string
- var m2 map[int][]byte
- fn(t, b, &m1)
- fn(t, b, &m2)
- // an extension claiming to have 0x7fffffff bytes, but only has 1.
- b = []byte{0xc9, 0x7f, 0xff, 0xff, 0xff, 0xda, 0x1}
- var a interface{}
- fn(t, b, &a)
- // b = []byte{0x00}
- // var s testSelferRecur
- // fn(t, b, &s)
- }
- func TestMapRangeIndex(t *testing.T) {
- // t.Skip()
- type T struct {
- I int
- S string
- B bool
- M map[int]T
- }
- t1 := T{I: 1, B: true, S: "11", M: map[int]T{11: T{I: 11}}}
- t2 := T{I: 1, B: true, S: "12", M: map[int]T{12: T{I: 12}}}
- // ------
- var m1 = map[string]*T{
- "11": &t1,
- "12": &t2,
- }
- var m1c = make(map[string]T)
- for k, v := range m1 {
- m1c[k] = *v
- }
- fnrv := func(r1, r2 reflect.Value) reflect.Value {
- if r1.IsValid() {
- return r1
- }
- return r2
- }
- // var vx reflect.Value
- mt := reflect.TypeOf(m1)
- rvk := mapAddressableRV(mt.Key(), mt.Key().Kind())
- rvv := mapAddressableRV(mt.Elem(), mt.Elem().Kind())
- var it mapIter
- mapRange(&it, rv4i(m1), rvk, rvv, true)
- for it.Next() {
- k := fnrv(it.Key(), rvk).Interface().(string)
- v := fnrv(it.Value(), rvv).Interface().(*T)
- testDeepEqualErr(m1[k], v, t, "map-key-eq-it-key")
- if _, ok := m1c[k]; ok {
- delete(m1c, k)
- } else {
- t.Logf("unexpected key in map: %v", k)
- t.FailNow()
- }
- }
- it.Done()
- testDeepEqualErr(len(m1c), 0, t, "all-keys-not-consumed")
- // ------
- var m2 = map[*T]T{
- &t1: t1,
- &t2: t2,
- }
- var m2c = make(map[*T]*T)
- for k := range m2 {
- m2c[k] = k
- }
- mt = reflect.TypeOf(m2)
- rvk = mapAddressableRV(mt.Key(), mt.Key().Kind())
- rvv = mapAddressableRV(mt.Elem(), mt.Elem().Kind())
- mapRange(&it, rv4i(m2), rvk, rvv, true)
- for it.Next() {
- k := fnrv(it.Key(), rvk).Interface().(*T)
- v := fnrv(it.Value(), rvv).Interface().(T)
- testDeepEqualErr(m2[k], v, t, "map-key-eq-it-key")
- if _, ok := m2c[k]; ok {
- delete(m2c, k)
- } else {
- t.Logf("unexpected key in map: %v", k)
- t.FailNow()
- }
- }
- it.Done()
- testDeepEqualErr(len(m2c), 0, t, "all-keys-not-consumed")
- // ---- test mapGet
- fnTestMapIndex := func(mi ...interface{}) {
- for _, m0 := range mi {
- m := rv4i(m0)
- rvv := mapAddressableRV(m.Type().Elem(), m.Type().Elem().Kind())
- for _, k := range m.MapKeys() {
- testDeepEqualErr(m.MapIndex(k).Interface(), mapGet(m, k, rvv).Interface(), t, "map-index-eq")
- }
- }
- }
- fnTestMapIndex(m1, m1c, m2, m2c)
- // var s string = "hello"
- // var tt = &T{I: 3}
- // ttTyp := reflect.TypeOf(tt)
- // _, _ = tt, ttTyp
- // mv := rv4i(m)
- // it := mapRange(mv, rv4i(&s).Elem(), rv4i(&tt).Elem(), true) //ok
- // it := mapRange(mv, reflect.New(reflect.TypeOf(s)).Elem(), reflect.New(reflect.TypeOf(T{})).Elem(), true) // ok
- // it := mapRange(mv, reflect.New(reflect.TypeOf(s)).Elem(), reflect.New(ttTyp.Elem()), true) // !ok
- // it := mapRange(mv, reflect.New(reflect.TypeOf(s)).Elem(), reflect.New(reflect.TypeOf(T{})), true) !ok
- // it := mapRange(mv, reflect.New(reflect.TypeOf(s)).Elem(), reflect.New(reflect.TypeOf(T{})).Elem(), true) // ok
- // fmt.Printf("key: %#v\n", it.Key())
- // fmt.Printf("exp: %#v\n", mv.MapIndex(it.Key()))
- // fmt.Printf("val: %#v\n", it.Value())
- // testDeepEqualErr(mv.MapIndex(it.Key()), it.Value().Interface()
- }
- // ----------
- func TestBincCodecsTable(t *testing.T) {
- testCodecTableOne(t, testBincH)
- }
- func TestBincCodecsMisc(t *testing.T) {
- testCodecMiscOne(t, testBincH)
- }
- func TestBincCodecsEmbeddedPointer(t *testing.T) {
- testCodecEmbeddedPointer(t, testBincH)
- }
- func TestBincStdEncIntf(t *testing.T) {
- doTestStdEncIntf(t, testBincH)
- }
- func TestBincMammoth(t *testing.T) {
- testMammoth(t, testBincH)
- }
- func TestSimpleCodecsTable(t *testing.T) {
- testCodecTableOne(t, testSimpleH)
- }
- func TestSimpleCodecsMisc(t *testing.T) {
- testCodecMiscOne(t, testSimpleH)
- }
- func TestSimpleCodecsEmbeddedPointer(t *testing.T) {
- testCodecEmbeddedPointer(t, testSimpleH)
- }
- func TestSimpleStdEncIntf(t *testing.T) {
- doTestStdEncIntf(t, testSimpleH)
- }
- func TestSimpleMammoth(t *testing.T) {
- testMammoth(t, testSimpleH)
- }
- func TestMsgpackCodecsTable(t *testing.T) {
- testCodecTableOne(t, testMsgpackH)
- }
- func TestMsgpackCodecsMisc(t *testing.T) {
- testCodecMiscOne(t, testMsgpackH)
- }
- func TestMsgpackCodecsEmbeddedPointer(t *testing.T) {
- testCodecEmbeddedPointer(t, testMsgpackH)
- }
- func TestMsgpackStdEncIntf(t *testing.T) {
- doTestStdEncIntf(t, testMsgpackH)
- }
- func TestMsgpackMammoth(t *testing.T) {
- testMammoth(t, testMsgpackH)
- }
- func TestCborCodecsTable(t *testing.T) {
- testCodecTableOne(t, testCborH)
- }
- func TestCborCodecsMisc(t *testing.T) {
- testCodecMiscOne(t, testCborH)
- }
- func TestCborCodecsEmbeddedPointer(t *testing.T) {
- testCodecEmbeddedPointer(t, testCborH)
- }
- func TestCborCodecChan(t *testing.T) {
- testCodecChan(t, testCborH)
- }
- func TestCborStdEncIntf(t *testing.T) {
- doTestStdEncIntf(t, testCborH)
- }
- func TestCborMammoth(t *testing.T) {
- testMammoth(t, testCborH)
- }
- func TestJsonCodecsTable(t *testing.T) {
- testCodecTableOne(t, testJsonH)
- }
- func TestJsonCodecsMisc(t *testing.T) {
- testCodecMiscOne(t, testJsonH)
- }
- func TestJsonCodecsEmbeddedPointer(t *testing.T) {
- testCodecEmbeddedPointer(t, testJsonH)
- }
- func TestJsonCodecChan(t *testing.T) {
- testCodecChan(t, testJsonH)
- }
- func TestJsonStdEncIntf(t *testing.T) {
- doTestStdEncIntf(t, testJsonH)
- }
- func TestJsonMammothA(t *testing.T) {
- testMammoth(t, testJsonH)
- }
- // ----- Raw ---------
- func TestJsonRaw(t *testing.T) {
- doTestRawValue(t, testJsonH)
- }
- func TestBincRaw(t *testing.T) {
- doTestRawValue(t, testBincH)
- }
- func TestMsgpackRaw(t *testing.T) {
- doTestRawValue(t, testMsgpackH)
- }
- func TestSimpleRaw(t *testing.T) {
- doTestRawValue(t, testSimpleH)
- }
- func TestCborRaw(t *testing.T) {
- doTestRawValue(t, testCborH)
- }
- // ----- ALL (framework based) -----
- func TestAllEncCircularRef(t *testing.T) {
- doTestEncCircularRef(t, testCborH)
- }
- func TestAllAnonCycle(t *testing.T) {
- doTestAnonCycle(t, testCborH)
- }
- func TestAllErrWriter(t *testing.T) {
- doTestErrWriter(t, testCborH)
- doTestErrWriter(t, testJsonH)
- }
- // ----- RPC custom -----
- func TestMsgpackRpcSpec(t *testing.T) {
- testCodecRpcOne(t, MsgpackSpecRpc, testMsgpackH, true, 0)
- }
- // ----- RPC -----
- func TestBincRpcGo(t *testing.T) {
- testCodecRpcOne(t, GoRpc, testBincH, true, 0)
- }
- func TestSimpleRpcGo(t *testing.T) {
- testCodecRpcOne(t, GoRpc, testSimpleH, true, 0)
- }
- func TestMsgpackRpcGo(t *testing.T) {
- testCodecRpcOne(t, GoRpc, testMsgpackH, true, 0)
- }
- func TestCborRpcGo(t *testing.T) {
- testCodecRpcOne(t, GoRpc, testCborH, true, 0)
- }
- func TestJsonRpcGo(t *testing.T) {
- testCodecRpcOne(t, GoRpc, testJsonH, true, 0)
- }
- // ----- OTHERS -----
- func TestBincMapEncodeForCanonical(t *testing.T) {
- t.Skip() // TODO: testing fails??? Need to research
- doTestMapEncodeForCanonical(t, testBincH)
- }
- func TestSimpleMapEncodeForCanonical(t *testing.T) {
- doTestMapEncodeForCanonical(t, testSimpleH)
- }
- func TestMsgpackMapEncodeForCanonical(t *testing.T) {
- doTestMapEncodeForCanonical(t, testMsgpackH)
- }
- func TestCborMapEncodeForCanonical(t *testing.T) {
- doTestMapEncodeForCanonical(t, testCborH)
- }
- func TestJsonMapEncodeForCanonical(t *testing.T) {
- doTestMapEncodeForCanonical(t, testJsonH)
- }
- func TestBincUnderlyingType(t *testing.T) {
- testCodecUnderlyingType(t, testBincH)
- }
- func TestJsonSwallowAndZero(t *testing.T) {
- doTestSwallowAndZero(t, testJsonH)
- }
- func TestCborSwallowAndZero(t *testing.T) {
- doTestSwallowAndZero(t, testCborH)
- }
- func TestMsgpackSwallowAndZero(t *testing.T) {
- doTestSwallowAndZero(t, testMsgpackH)
- }
- func TestBincSwallowAndZero(t *testing.T) {
- doTestSwallowAndZero(t, testBincH)
- }
- func TestSimpleSwallowAndZero(t *testing.T) {
- doTestSwallowAndZero(t, testSimpleH)
- }
- func TestJsonRawExt(t *testing.T) {
- doTestRawExt(t, testJsonH)
- }
- func TestCborRawExt(t *testing.T) {
- doTestRawExt(t, testCborH)
- }
- func TestMsgpackRawExt(t *testing.T) {
- doTestRawExt(t, testMsgpackH)
- }
- func TestBincRawExt(t *testing.T) {
- doTestRawExt(t, testBincH)
- }
- func TestSimpleRawExt(t *testing.T) {
- doTestRawExt(t, testSimpleH)
- }
- func TestJsonMapStructKey(t *testing.T) {
- doTestMapStructKey(t, testJsonH)
- }
- func TestCborMapStructKey(t *testing.T) {
- doTestMapStructKey(t, testCborH)
- }
- func TestMsgpackMapStructKey(t *testing.T) {
- doTestMapStructKey(t, testMsgpackH)
- }
- func TestBincMapStructKey(t *testing.T) {
- doTestMapStructKey(t, testBincH)
- }
- func TestSimpleMapStructKey(t *testing.T) {
- doTestMapStructKey(t, testSimpleH)
- }
- func TestJsonDecodeNilMapValue(t *testing.T) {
- doTestDecodeNilMapValue(t, testJsonH)
- }
- func TestCborDecodeNilMapValue(t *testing.T) {
- doTestDecodeNilMapValue(t, testCborH)
- }
- func TestMsgpackDecodeNilMapValue(t *testing.T) {
- doTestDecodeNilMapValue(t, testMsgpackH)
- }
- func TestBincDecodeNilMapValue(t *testing.T) {
- doTestDecodeNilMapValue(t, testBincH)
- }
- func TestSimpleDecodeNilMapValue(t *testing.T) {
- doTestDecodeNilMapValue(t, testSimpleH)
- }
- func TestJsonEmbeddedFieldPrecedence(t *testing.T) {
- doTestEmbeddedFieldPrecedence(t, testJsonH)
- }
- func TestCborEmbeddedFieldPrecedence(t *testing.T) {
- doTestEmbeddedFieldPrecedence(t, testCborH)
- }
- func TestMsgpackEmbeddedFieldPrecedence(t *testing.T) {
- doTestEmbeddedFieldPrecedence(t, testMsgpackH)
- }
- func TestBincEmbeddedFieldPrecedence(t *testing.T) {
- doTestEmbeddedFieldPrecedence(t, testBincH)
- }
- func TestSimpleEmbeddedFieldPrecedence(t *testing.T) {
- doTestEmbeddedFieldPrecedence(t, testSimpleH)
- }
- func TestJsonLargeContainerLen(t *testing.T) {
- doTestLargeContainerLen(t, testJsonH)
- }
- func TestCborLargeContainerLen(t *testing.T) {
- doTestLargeContainerLen(t, testCborH)
- }
- func TestMsgpackLargeContainerLen(t *testing.T) {
- doTestLargeContainerLen(t, testMsgpackH)
- }
- func TestBincLargeContainerLen(t *testing.T) {
- doTestLargeContainerLen(t, testBincH)
- }
- func TestSimpleLargeContainerLen(t *testing.T) {
- doTestLargeContainerLen(t, testSimpleH)
- }
- func TestJsonMammothMapsAndSlices(t *testing.T) {
- doTestMammothMapsAndSlices(t, testJsonH)
- }
- func TestCborMammothMapsAndSlices(t *testing.T) {
- doTestMammothMapsAndSlices(t, testCborH)
- }
- func TestMsgpackMammothMapsAndSlices(t *testing.T) {
- old1 := testMsgpackH.WriteExt
- defer func() { testMsgpackH.WriteExt = old1 }()
- testMsgpackH.WriteExt = true
- doTestMammothMapsAndSlices(t, testMsgpackH)
- }
- func TestBincMammothMapsAndSlices(t *testing.T) {
- doTestMammothMapsAndSlices(t, testBincH)
- }
- func TestSimpleMammothMapsAndSlices(t *testing.T) {
- doTestMammothMapsAndSlices(t, testSimpleH)
- }
- func TestJsonTime(t *testing.T) {
- testTime(t, testJsonH)
- }
- func TestCborTime(t *testing.T) {
- testTime(t, testCborH)
- }
- func TestMsgpackTime(t *testing.T) {
- testTime(t, testMsgpackH)
- }
- func TestBincTime(t *testing.T) {
- testTime(t, testBincH)
- }
- func TestSimpleTime(t *testing.T) {
- testTime(t, testSimpleH)
- }
- func TestJsonUintToInt(t *testing.T) {
- testUintToInt(t, testJsonH)
- }
- func TestCborUintToInt(t *testing.T) {
- testUintToInt(t, testCborH)
- }
- func TestMsgpackUintToInt(t *testing.T) {
- testUintToInt(t, testMsgpackH)
- }
- func TestBincUintToInt(t *testing.T) {
- testUintToInt(t, testBincH)
- }
- func TestSimpleUintToInt(t *testing.T) {
- testUintToInt(t, testSimpleH)
- }
- func TestJsonDifferentMapOrSliceType(t *testing.T) {
- doTestDifferentMapOrSliceType(t, testJsonH)
- }
- func TestCborDifferentMapOrSliceType(t *testing.T) {
- doTestDifferentMapOrSliceType(t, testCborH)
- }
- func TestMsgpackDifferentMapOrSliceType(t *testing.T) {
- doTestDifferentMapOrSliceType(t, testMsgpackH)
- }
- func TestBincDifferentMapOrSliceType(t *testing.T) {
- doTestDifferentMapOrSliceType(t, testBincH)
- }
- func TestSimpleDifferentMapOrSliceType(t *testing.T) {
- doTestDifferentMapOrSliceType(t, testSimpleH)
- }
- func TestJsonScalars(t *testing.T) {
- doTestScalars(t, testJsonH)
- }
- func TestCborScalars(t *testing.T) {
- doTestScalars(t, testCborH)
- }
- func TestMsgpackScalars(t *testing.T) {
- doTestScalars(t, testMsgpackH)
- }
- func TestBincScalars(t *testing.T) {
- doTestScalars(t, testBincH)
- }
- func TestSimpleScalars(t *testing.T) {
- doTestScalars(t, testSimpleH)
- }
- func TestJsonOmitempty(t *testing.T) {
- doTestOmitempty(t, testJsonH)
- }
- func TestCborOmitempty(t *testing.T) {
- doTestOmitempty(t, testCborH)
- }
- func TestMsgpackOmitempty(t *testing.T) {
- doTestOmitempty(t, testMsgpackH)
- }
- func TestBincOmitempty(t *testing.T) {
- doTestOmitempty(t, testBincH)
- }
- func TestSimpleOmitempty(t *testing.T) {
- doTestOmitempty(t, testSimpleH)
- }
- func TestJsonIntfMapping(t *testing.T) {
- doTestIntfMapping(t, testJsonH)
- }
- func TestCborIntfMapping(t *testing.T) {
- doTestIntfMapping(t, testCborH)
- }
- func TestMsgpackIntfMapping(t *testing.T) {
- doTestIntfMapping(t, testMsgpackH)
- }
- func TestBincIntfMapping(t *testing.T) {
- doTestIntfMapping(t, testBincH)
- }
- func TestSimpleIntfMapping(t *testing.T) {
- doTestIntfMapping(t, testSimpleH)
- }
- func TestJsonMissingFields(t *testing.T) {
- doTestMissingFields(t, testJsonH)
- }
- func TestCborMissingFields(t *testing.T) {
- doTestMissingFields(t, testCborH)
- }
- func TestMsgpackMissingFields(t *testing.T) {
- doTestMissingFields(t, testMsgpackH)
- }
- func TestBincMissingFields(t *testing.T) {
- doTestMissingFields(t, testBincH)
- }
- func TestSimpleMissingFields(t *testing.T) {
- doTestMissingFields(t, testSimpleH)
- }
- func TestJsonMaxDepth(t *testing.T) {
- doTestMaxDepth(t, testJsonH)
- }
- func TestCborMaxDepth(t *testing.T) {
- doTestMaxDepth(t, testCborH)
- }
- func TestMsgpackMaxDepth(t *testing.T) {
- doTestMaxDepth(t, testMsgpackH)
- }
- func TestBincMaxDepth(t *testing.T) {
- doTestMaxDepth(t, testBincH)
- }
- func TestSimpleMaxDepth(t *testing.T) {
- doTestMaxDepth(t, testSimpleH)
- }
- func TestJsonSelfExt(t *testing.T) {
- doTestSelfExt(t, testJsonH)
- }
- func TestCborSelfExt(t *testing.T) {
- doTestSelfExt(t, testCborH)
- }
- func TestMsgpackSelfExt(t *testing.T) {
- doTestSelfExt(t, testMsgpackH)
- }
- func TestBincSelfExt(t *testing.T) {
- doTestSelfExt(t, testBincH)
- }
- func TestSimpleSelfExt(t *testing.T) {
- doTestSelfExt(t, testSimpleH)
- }
- func TestJsonBytesEncodedAsArray(t *testing.T) {
- doTestBytesEncodedAsArray(t, testJsonH)
- }
- func TestCborBytesEncodedAsArray(t *testing.T) {
- doTestBytesEncodedAsArray(t, testCborH)
- }
- func TestMsgpackBytesEncodedAsArray(t *testing.T) {
- doTestBytesEncodedAsArray(t, testMsgpackH)
- }
- func TestBincBytesEncodedAsArray(t *testing.T) {
- doTestBytesEncodedAsArray(t, testBincH)
- }
- func TestSimpleBytesEncodedAsArray(t *testing.T) {
- doTestBytesEncodedAsArray(t, testSimpleH)
- }
- func TestJsonStrucEncDec(t *testing.T) {
- doTestStrucEncDec(t, testJsonH)
- }
- func TestCborStrucEncDec(t *testing.T) {
- doTestStrucEncDec(t, testCborH)
- }
- func TestMsgpackStrucEncDec(t *testing.T) {
- doTestStrucEncDec(t, testMsgpackH)
- }
- func TestBincStrucEncDec(t *testing.T) {
- doTestStrucEncDec(t, testBincH)
- }
- func TestSimpleStrucEncDec(t *testing.T) {
- doTestStrucEncDec(t, testSimpleH)
- }
- func TestJsonRawToStringToRawEtc(t *testing.T) {
- doTestRawToStringToRawEtc(t, testJsonH)
- }
- func TestCborRawToStringToRawEtc(t *testing.T) {
- doTestRawToStringToRawEtc(t, testCborH)
- }
- func TestMsgpackRawToStringToRawEtc(t *testing.T) {
- doTestRawToStringToRawEtc(t, testMsgpackH)
- }
- func TestBincRawToStringToRawEtc(t *testing.T) {
- doTestRawToStringToRawEtc(t, testBincH)
- }
- func TestSimpleRawToStringToRawEtc(t *testing.T) {
- doTestRawToStringToRawEtc(t, testSimpleH)
- }
- func TestJsonStructKeyType(t *testing.T) {
- doTestStructKeyType(t, testJsonH)
- }
- func TestCborStructKeyType(t *testing.T) {
- doTestStructKeyType(t, testCborH)
- }
- func TestMsgpackStructKeyType(t *testing.T) {
- doTestStructKeyType(t, testMsgpackH)
- }
- func TestBincStructKeyType(t *testing.T) {
- doTestStructKeyType(t, testBincH)
- }
- func TestSimpleStructKeyType(t *testing.T) {
- doTestStructKeyType(t, testSimpleH)
- }
- func TestJsonPreferArrayOverSlice(t *testing.T) {
- doTestPreferArrayOverSlice(t, testJsonH)
- }
- func TestCborPreferArrayOverSlice(t *testing.T) {
- doTestPreferArrayOverSlice(t, testCborH)
- }
- func TestMsgpackPreferArrayOverSlice(t *testing.T) {
- doTestPreferArrayOverSlice(t, testMsgpackH)
- }
- func TestBincPreferArrayOverSlice(t *testing.T) {
- doTestPreferArrayOverSlice(t, testBincH)
- }
- func TestSimplePreferArrayOverSlice(t *testing.T) {
- doTestPreferArrayOverSlice(t, testSimpleH)
- }
- func TestJsonZeroCopyBytes(t *testing.T) {
- doTestZeroCopyBytes(t, testJsonH)
- }
- func TestCborZeroCopyBytes(t *testing.T) {
- doTestZeroCopyBytes(t, testCborH)
- }
- func TestMsgpackZeroCopyBytes(t *testing.T) {
- doTestZeroCopyBytes(t, testMsgpackH)
- }
- func TestBincZeroCopyBytes(t *testing.T) {
- doTestZeroCopyBytes(t, testBincH)
- }
- func TestSimpleZeroCopyBytes(t *testing.T) {
- doTestZeroCopyBytes(t, testSimpleH)
- }
- // --------
- func TestMultipleEncDec(t *testing.T) {
- doTestMultipleEncDec(t, testJsonH)
- }
- // TODO:
- //
- // Add Tests for the following:
- // - struct tags: on anonymous fields, _struct (all fields), etc
- // - chan to encode and decode (with support for codecgen also)
- //
- // Add negative tests for failure conditions:
- // - bad input with large array length prefix
- //
- // Add tests for decode.go (standalone)
- // - UnreadByte: only 2 states (z.ls = 2 and z.ls = 1) (0 --> 2 --> 1)
- // - track: z.trb: track, stop track, check
- // - PreferArrayOverSlice???
- // - InterfaceReset
- // - (chan byte) to decode []byte (with mapbyslice track)
- // - decode slice of len 6, 16 into slice of (len 4, cap 8) and (len ) with maxinitlen=6, 8, 16
- // - DeleteOnNilMapValue
- // - decnaked: n.l == nil
- // - ensureDecodeable (try to decode into a non-decodeable thing e.g. a nil interface{},
- //
- // Add tests for encode.go (standalone)
- // - nil and 0-len slices and maps for non-fastpath things
|