Simplified the API: There's only one constructor, and it does everything necessary to initiate the stream. StartSession() and Roster.Update() have both been eliminated.
packagexmppimport("fmt""strconv""testing")funcTestCloseIn(t*testing.T){add:=make(chanFilter)in:=make(chanStanza)out:=make(chanStanza)gofilterMgr(add,in,out)close(in)_,ok:=<-outifok{fmt.Errorf("out didn't close")}}funcpassthru(in<-chanStanza,outchan<-Stanza){deferclose(out)forstan:=rangein{out<-stan}}funcTestFilters(t*testing.T){forn:=0;n<10;n++{filterN(n,t)}}funcfilterN(numFiltsint,t*testing.T){add:=make(chanFilter)in:=make(chanStanza)deferclose(in)out:=make(chanStanza)gofilterMgr(add,in,out)fori:=0;i<numFilts;i++{add<-passthru}gofunc(){fori:=0;i<100;i++{msg:=Message{}msg.Id=fmt.Sprintf("%d",i)in<-&msg}}()fori:=0;i<100;i++{stan:=<-outmsg,ok:=stan.(*Message)if!ok{t.Errorf("N = %d: msg %d not a Message: %#v",numFilts,i,stan)continue}n,err:=strconv.Atoi(msg.Header.Id)iferr!=nil{t.Errorf("N = %d: msg %d parsing ID '%s': %v",numFilts,i,msg.Header.Id,err)continue}ifn!=i{t.Errorf("N = %d: msg %d wrong id %d",numFilts,i,n)}}}