guesstimate/server/internal/diffsync/json/json_test.go

170 lines
3.8 KiB
Go

package json
import (
"encoding/json"
"fmt"
"log"
"reflect"
"testing"
"forge.cadoles.com/wpetit/guesstimate/internal/diffsync"
"github.com/davecgh/go-spew/spew"
)
func TestJSONSync(t *testing.T) {
doc1 := diffsync.NewDocument(
[]byte("{}"),
WithJSONSync(),
)
doc2 := diffsync.NewDocument(
[]byte("{}"),
WithJSONSync(),
)
p1 := doc1.NewPeer()
p2 := doc2.NewPeer()
log.Printf("p1 shadow: %s", p1.Shadow().Content())
log.Printf("p2 shadow: %s", p2.Shadow().Content())
newContent1 := []byte(`{"hello":"world"}`)
log.Printf("updating doc1 with '%s'", newContent1)
stack1, err := p1.Update(newContent1)
if err != nil {
t.Error(err)
}
log.Printf("applying stack1 to doc2 '%s'", doc2.Content())
if err := p2.Apply(stack1); err != nil {
t.Error(err)
}
log.Printf("new doc2 content: '%s'", doc2.Content())
if g, e := doc2.Content(), doc1.Content(); !jsonEqual(e, g) {
t.Errorf("doc2.Content(): expected '%s', got '%s'", e, g)
}
}
type testStep struct {
Local *diffsync.Peer
Remote *diffsync.Peer
Update string
MatchLocal bool
MatchRemote bool
}
func TestBidirectionnalUpdate(t *testing.T) {
doc1 := diffsync.NewDocument([]byte(`{}`), WithJSONSync())
doc2 := diffsync.NewDocument([]byte(`{}`), WithJSONSync())
p1 := doc1.NewPeer()
p2 := doc2.NewPeer()
var cases = []testStep{
{
Local: p1,
Remote: p2,
Update: `{"hello":"world"}`,
MatchLocal: true,
MatchRemote: true,
},
{
Local: p2,
Remote: p1,
Update: `{"hello":"world","foo":"bar"}`,
MatchLocal: true,
MatchRemote: true,
},
{
Local: p1,
Remote: p2,
Update: `{"hello":1,"foo":"bar"}`,
MatchLocal: true,
MatchRemote: true,
},
{
Local: p1,
Remote: nil,
Update: `{"hello":1,"foo":"bar", "test":{"bar": "baz"}}`,
MatchLocal: true,
MatchRemote: false,
},
{
Local: p2,
Remote: p1,
Update: `{"hello":2,"foo":"bar", "test":{"bar": "baz","world":"hello"}}`,
MatchLocal: true,
MatchRemote: true,
},
}
for i, step := range cases {
func(step testStep, i int) {
t.Run(fmt.Sprintf("Step %d", i), func(t *testing.T) {
log.Printf("local document before update: '%s'", step.Local.Document().Content())
stack, err := step.Local.Update([]byte(step.Update))
if err != nil {
t.Error(err)
}
log.Printf("local document after update: '%s'", step.Local.Document().Content())
log.Printf("resulting stack: '%s'", spew.Sdump(stack))
if step.MatchLocal {
if e, g := step.Local.Document().Content(), []byte(step.Update); !jsonEqual(e, g) {
t.Errorf("local.Document().Content(): expected '%s', got '%s'", e, g)
}
}
if step.Remote != nil {
log.Printf("remote document before apply: '%s'", step.Remote.Document().Content())
if err := step.Remote.Apply(stack); err != nil {
t.Error(err)
}
log.Printf("remote document after apply: '%s'", step.Remote.Document().Content())
}
if step.MatchRemote {
if e, g := step.Remote.Document().Content(), []byte(step.Update); !jsonEqual(e, g) {
t.Errorf("remote.Document().Content(): expected '%s', got '%s'", e, g)
}
}
if step.MatchLocal && step.MatchRemote {
if e, g := step.Local.Document().Content(), step.Remote.Document().Content(); !jsonEqual(e, g) {
t.Errorf("local.Document().Content() should match remote.Document().Content() ! Got '%s' and '%s'", e, g)
}
}
})
}(step, i)
}
}
func jsonEqual(s1, s2 []byte) bool {
var (
o1 interface{}
o2 interface{}
)
var err error
err = json.Unmarshal(s1, &o1)
if err != nil {
panic(fmt.Errorf("Error mashalling []byte 1 :: %s", err.Error()))
}
err = json.Unmarshal(s2, &o2)
if err != nil {
panic(fmt.Errorf("Error mashalling []byte 2 :: %s", err.Error()))
}
return reflect.DeepEqual(o1, o2)
}