170 lines
3.8 KiB
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)
|
||
|
}
|