package caddyhugo
import (
"path"
"sync"
"testing"
"time"
"git.stephensearles.com/stephen/acedoc"
)
func TestEdits ( t * testing . T ) {
w := NewWorld ( t )
defer w . Clean ( )
const title = "sometitle"
var (
mtx sync . Mutex
contentPath = path . Join ( "content" , title + ".md" )
// we will send these to the doc
send = [ ] acedoc . Delta {
acedoc . Insert ( 0 , 0 , "hello" ) ,
acedoc . Insert ( 0 , 5 , " world" ) ,
acedoc . Insert ( 0 , 11 , " world" ) ,
}
// we will use this to track what we get out of the doc
received = [ ] acedoc . Delta { }
)
// prepare a new post
w . CH . NewContent ( title , "" )
// start an edit session
es , err := w . CH . editSession ( contentPath )
if err != nil {
t . Fatal ( "error creating document client:" , err )
}
// register a client that we will use to push the deltas. we dont need
// to actually do anything to receive deltas here, though.
c := es . doc . Client ( acedoc . DeltaHandlerFunc ( func ( ds [ ] acedoc . Delta ) error {
return nil
} ) )
// register an *extra* client that just adds to the received delta
// slice we're tracking
es . doc . Client ( acedoc . DeltaHandlerFunc ( func ( ds [ ] acedoc . Delta ) error {
mtx . Lock ( )
defer mtx . Unlock ( )
received = append ( received , ds ... )
return nil
} ) )
// make sure we have an edit session
_ , ok := w . CH . hasEditSession ( contentPath )
if ! ok {
t . Fatal ( "expected there to be an established client" )
}
// push the deltas
c . PushDeltas ( send ... )
// wait...
<- time . After ( 5 * time . Second )
// be sure we got the correct number of deltas back
mtx . Lock ( )
defer mtx . Unlock ( )
if len ( received ) != len ( send ) {
t . Errorf ( "expected %d deltas, received %d; expected: %v, received: %v" , len ( send ) , len ( received ) , send , received )
}
}
func TestDeltasSingle ( t * testing . T ) {
w := NewWorld ( t )
defer w . Clean ( )
const title = "test"
_ , err := w . CH . NewContent ( title , "" )
if err != nil {
t . Fatal ( "couldn't create new content:" , err )
}
client := new ( WebsocketTester )
es , err := w . CH . editSession ( "content/" + title + ".md" )
if err != nil {
t . Fatal ( "couldn't establish docref for client 0:" , err )
}
go w . CH . handleDeltaConn ( client , es )
a := acedoc . Insert ( 0 , 0 , "a" )
// pretend to get one sent from the "browser"
client . ReceiveJSON ( w . CH . Message ( a ) )
// wait to make sure it was processed
time . Sleep ( 50 * time . Millisecond )
// we shouldn't have written back to the client,
// so we expect to have written 0 *deltas*. (we may have written
// empty messages without deltas because of the pings to the client)
if len ( client . wroteDeltas ) != 0 {
t . Errorf ( "client wrote %d deltas, should have written %d" , len ( client . wroteMessages ) , 0 )
t . Logf ( "%v" , client . wroteMessages )
}
// we received one, so make sure that's counted properly
if len ( client . received ) != 1 {
t . Errorf ( "client has %d messages, should have received %d" , len ( client . received ) , 1 )
}
}
func TestDeltasDouble ( t * testing . T ) {
w := NewWorld ( t )
defer w . Clean ( )
const title = "test"
_ , err := w . CH . NewContent ( title , "" )
if err != nil {
t . Fatal ( "couldn't create new content:" , err )
}
clientA := new ( WebsocketTester )
clientB := new ( WebsocketTester )
doc , err := w . CH . editSession ( "content/" + title + ".md" )
if err != nil {
t . Fatal ( "couldn't establish docref for client 0:" , err )
}
go w . CH . handleDeltaConn ( clientA , doc )
go w . CH . handleDeltaConn ( clientB , doc )
// send the first message, simulating the browser on clientA
clientA . ReceiveJSON ( w . CH . Message ( acedoc . Insert ( 0 , 0 , "a" ) ) )
time . Sleep ( 100 * time . Millisecond )
clientA . mtx . Lock ( )
clientB . mtx . Lock ( )
// so we expect clientA to have written 0 messages, and
// clientB to have written 1
if len ( clientA . wroteDeltas ) != 0 || len ( clientB . wroteDeltas ) != 1 {
t . Errorf ( "clientA wrote %d messages, should have written 0. clientB wrote %d, should have written 1" , len ( clientA . wroteMessages ) , len ( clientB . wroteMessages ) )
}
// we received one via clientA and zero via clientB, so make sure
// that's counted properly
if len ( clientA . received ) != 1 || len ( clientB . received ) != 0 {
t . Errorf ( "clientA has %d messages, should have received 1; clientB has %d messages, should have received 0" , len ( clientA . received ) , len ( clientB . received ) )
}
clientA . mtx . Unlock ( )
clientB . mtx . Unlock ( )
// send the second message, via clientB
clientB . ReceiveJSON ( w . CH . Message ( acedoc . Insert ( 0 , 0 , "b" ) ) )
time . Sleep ( 400 * time . Millisecond )
clientA . mtx . Lock ( )
clientB . mtx . Lock ( )
// so we expect clientA to have written 1 delta this time, and
// clientB to have written nothing new, so 1 still
if len ( clientA . wroteDeltas ) != 1 || len ( clientB . wroteDeltas ) != 1 {
t . Errorf ( "clientA wrote %d messages, should have written 1. clientB wrote %d, should have written 1 (just from before)" , len ( clientA . wroteMessages ) , len ( clientB . wroteMessages ) )
}
// we received zero (new) via clientA and one via clientB, so make sure
// that's counted properly
if len ( clientA . received ) != 1 || len ( clientB . received ) != 1 {
t . Errorf ( "clientA has %d messages, should have received 1; clientB has %d messages, should have received 1" , len ( clientA . received ) , len ( clientB . received ) )
}
clientA . mtx . Unlock ( )
clientB . mtx . Unlock ( )
}
func TestDeltasMulti ( t * testing . T ) {
w := NewWorld ( t )
defer w . Clean ( )
const title = "test"
_ , err := w . CH . NewContent ( title , "" )
if err != nil {
t . Fatal ( "couldn't create new content:" , err )
}
clients := [ ] * WebsocketTester { { } , { } , { } }
doc , err := w . CH . editSession ( "content/" + title + ".md" )
if err != nil {
t . Fatal ( "couldn't establish edit session:" , err )
}
go w . CH . handleDeltaConn ( clients [ 0 ] , doc )
go w . CH . handleDeltaConn ( clients [ 1 ] , doc )
go w . CH . handleDeltaConn ( clients [ 2 ] , doc )
time . Sleep ( 100 * time . Millisecond )
a := acedoc . Insert ( 0 , 0 , "a" )
b := acedoc . Insert ( 0 , 0 , "b" )
c := acedoc . Insert ( 0 , 0 , "c" )
clients [ 0 ] . ReceiveJSON ( w . CH . Message ( a ) )
clients [ 1 ] . ReceiveJSON ( w . CH . Message ( b ) )
clients [ 2 ] . ReceiveJSON ( w . CH . Message ( c ) )
time . Sleep ( 1000 * time . Millisecond )
for i , client := range clients {
client . mtx . Lock ( )
// all clients should have "written" 2 deltas out to their "browser"
// that came from the other clients
if len ( client . wroteDeltas ) != 2 {
t . Errorf ( "client %d wrote %d deltas, should have written 2" , i , len ( client . wroteDeltas ) )
}
// all clients "received" 1 message from the "browser"
if len ( client . received ) != 1 {
t . Errorf ( "client %d has %d messages, should have received 1" , i , len ( client . received ) )
}
client . mtx . Unlock ( )
}
}
func TestPagesInPagesOut ( t * testing . T ) {
w := NewWorld ( t )
defer w . Clean ( )
// check there's no content at first
c , err := GetContent ( w . BlogFolder , w . CH . HugoSites )
if err != nil {
t . Fatalf ( "couldn't get content from a blank test environment: %v" , err )
}
if len ( c ) != 0 {
t . Fatalf ( "expected a blank test environment, but saw %d pages" , len ( c ) )
}
titles := [ ] string {
"test1" ,
"TEST 2!!" ,
}
found := map [ string ] bool { }
// create some known content
for i , title := range titles {
w . CH . NewContent ( title , "" )
c , err = GetContent ( w . BlogFolder , w . CH . HugoSites )
if err != nil {
t . Fatalf ( "couldn't get content from the test environment: %v" , err )
}
if len ( c ) - 1 != i {
t . Fatalf ( "expected %d page, but saw %d pages" , i + 1 , len ( c ) )
}
}
// make sure we get the content out that we just created
c , err = GetContent ( w . BlogFolder , w . CH . HugoSites )
if err != nil {
t . Fatalf ( "couldn't get content from the test environment: %v" , err )
}
for _ , content := range c {
if content . Metadata == nil {
t . Errorf ( "didn't see metadata for %q" , content . Filename )
}
found [ content . Filename ] = true
}
var missingSomething bool
for _ , title := range titles {
adjusted := path . Join ( "content" , docname ( title ) + ".md" )
if ! found [ adjusted ] {
missingSomething = true
t . Errorf ( "expected to find title %q, but didn't see it" , adjusted )
}
}
if missingSomething {
t . Logf ( "found titles: %v" , found )
}
}