aboutsummaryrefslogtreecommitdiffstats
path: root/entity/dag
diff options
context:
space:
mode:
authorMichael Muré <batolettre@gmail.com>2022-08-24 21:29:17 +0200
committerMichael Muré <batolettre@gmail.com>2022-08-24 21:31:48 +0200
commite1b172aaf0e984791b5af4a64b144339fd4042f6 (patch)
tree1306f7f617968e13e6f28eda51417ae8cd2c6c6a /entity/dag
parentccb71fea57bb17f267f135cb008470615595c5b7 (diff)
downloadgit-bug-e1b172aaf0e984791b5af4a64b144339fd4042f6.tar.gz
dag: test op serialisation with the unmarshaller, to allow resolving entities
Diffstat (limited to 'entity/dag')
-rw-r--r--entity/dag/common_test.go11
-rw-r--r--entity/dag/entity.go4
-rw-r--r--entity/dag/example_test.go6
-rw-r--r--entity/dag/op_noop_test.go10
-rw-r--r--entity/dag/op_set_metadata_test.go10
-rw-r--r--entity/dag/operation_testing.go38
6 files changed, 35 insertions, 44 deletions
diff --git a/entity/dag/common_test.go b/entity/dag/common_test.go
index 713d0734..f78b09e9 100644
--- a/entity/dag/common_test.go
+++ b/entity/dag/common_test.go
@@ -141,16 +141,7 @@ func makeTestContextInternal(repo repository.ClockedRepo) (identity.Interface, i
}
resolvers := entity.Resolvers{
- &identity.Identity{}: entity.ResolverFunc(func(id entity.Id) (entity.Interface, error) {
- switch id {
- case id1.Id():
- return id1, nil
- case id2.Id():
- return id2, nil
- default:
- return nil, identity.ErrIdentityNotExist
- }
- }),
+ &identity.Identity{}: entity.MakeResolver(id1, id2),
}
def := Definition{
diff --git a/entity/dag/entity.go b/entity/dag/entity.go
index f9b55bd4..8b561274 100644
--- a/entity/dag/entity.go
+++ b/entity/dag/entity.go
@@ -19,6 +19,8 @@ const refsPattern = "refs/%s/%s"
const creationClockPattern = "%s-create"
const editClockPattern = "%s-edit"
+type OperationUnmarshaler func(raw json.RawMessage, resolver entity.Resolvers) (Operation, error)
+
// Definition hold the details defining one specialization of an Entity.
type Definition struct {
// the name of the entity (bug, pull-request, ...), for human consumption
@@ -26,7 +28,7 @@ type Definition struct {
// the Namespace in git references (bugs, prs, ...)
Namespace string
// a function decoding a JSON message into an Operation
- OperationUnmarshaler func(raw json.RawMessage, resolver entity.Resolvers) (Operation, error)
+ OperationUnmarshaler OperationUnmarshaler
// the expected format version number, that can be used for data migration/upgrade
FormatVersion uint
}
diff --git a/entity/dag/example_test.go b/entity/dag/example_test.go
index 9c6a4a62..b1511dc6 100644
--- a/entity/dag/example_test.go
+++ b/entity/dag/example_test.go
@@ -208,13 +208,13 @@ func NewProjectConfig() *ProjectConfig {
var def = dag.Definition{
Typename: "project config",
Namespace: "conf",
- OperationUnmarshaler: operationUnmarshaller,
+ OperationUnmarshaler: operationUnmarshaler,
FormatVersion: 1,
}
-// operationUnmarshaller is a function doing the de-serialization of the JSON data into our own
+// operationUnmarshaler is a function doing the de-serialization of the JSON data into our own
// concrete Operations. If needed, we can use the resolver to connect to other entities.
-func operationUnmarshaller(raw json.RawMessage, resolvers entity.Resolvers) (dag.Operation, error) {
+func operationUnmarshaler(raw json.RawMessage, resolvers entity.Resolvers) (dag.Operation, error) {
var t struct {
OperationType dag.OperationType `json:"type"`
}
diff --git a/entity/dag/op_noop_test.go b/entity/dag/op_noop_test.go
index c7710b83..61497b5b 100644
--- a/entity/dag/op_noop_test.go
+++ b/entity/dag/op_noop_test.go
@@ -1,13 +1,19 @@
package dag
import (
+ "encoding/json"
"testing"
"github.com/MichaelMure/git-bug/entities/identity"
+ "github.com/MichaelMure/git-bug/entity"
)
func TestNoopSerialize(t *testing.T) {
- SerializeRoundTripTest(t, func(author identity.Interface, unixTime int64) *NoOpOperation[*snapshotMock] {
- return NewNoOpOp[*snapshotMock](1, author, unixTime)
+ SerializeRoundTripTest(t, func(raw json.RawMessage, resolver entity.Resolvers) (Operation, error) {
+ var op NoOpOperation[*snapshotMock]
+ err := json.Unmarshal(raw, &op)
+ return &op, err
+ }, func(author identity.Interface, unixTime int64) (*NoOpOperation[*snapshotMock], entity.Resolvers) {
+ return NewNoOpOp[*snapshotMock](1, author, unixTime), nil
})
}
diff --git a/entity/dag/op_set_metadata_test.go b/entity/dag/op_set_metadata_test.go
index 49603021..f4f20e8e 100644
--- a/entity/dag/op_set_metadata_test.go
+++ b/entity/dag/op_set_metadata_test.go
@@ -1,10 +1,12 @@
package dag
import (
+ "encoding/json"
"testing"
"time"
"github.com/MichaelMure/git-bug/entities/identity"
+ "github.com/MichaelMure/git-bug/entity"
"github.com/MichaelMure/git-bug/repository"
"github.com/stretchr/testify/require"
@@ -97,10 +99,14 @@ func TestSetMetadata(t *testing.T) {
}
func TestSetMetadataSerialize(t *testing.T) {
- SerializeRoundTripTest(t, func(author identity.Interface, unixTime int64) *SetMetadataOperation[*snapshotMock] {
+ SerializeRoundTripTest(t, func(raw json.RawMessage, resolver entity.Resolvers) (Operation, error) {
+ var op SetMetadataOperation[*snapshotMock]
+ err := json.Unmarshal(raw, &op)
+ return &op, err
+ }, func(author identity.Interface, unixTime int64) (*SetMetadataOperation[*snapshotMock], entity.Resolvers) {
return NewSetMetadataOp[*snapshotMock](1, author, unixTime, "message", map[string]string{
"key1": "value1",
"key2": "value2",
- })
+ }), nil
})
}
diff --git a/entity/dag/operation_testing.go b/entity/dag/operation_testing.go
index 6ebdcae8..0ca47d4b 100644
--- a/entity/dag/operation_testing.go
+++ b/entity/dag/operation_testing.go
@@ -14,44 +14,30 @@ import (
// SerializeRoundTripTest realize a marshall/unmarshall round-trip in the same condition as with OperationPack,
// and check if the recovered operation is identical.
-func SerializeRoundTripTest[OpT Operation](t *testing.T, maker func(author identity.Interface, unixTime int64) OpT) {
+func SerializeRoundTripTest[OpT Operation](
+ t *testing.T,
+ unmarshaler OperationUnmarshaler,
+ maker func(author identity.Interface, unixTime int64) (OpT, entity.Resolvers),
+) {
repo := repository.NewMockRepo()
rene, err := identity.NewIdentity(repo, "René Descartes", "rene@descartes.fr")
require.NoError(t, err)
- op := maker(rene, time.Now().Unix())
+ op, resolvers := maker(rene, time.Now().Unix())
// enforce having an id
op.Id()
- rdt := &roundTripper[OpT]{Before: op, author: rene}
-
- data, err := json.Marshal(rdt)
+ data, err := json.Marshal(op)
require.NoError(t, err)
- err = json.Unmarshal(data, &rdt)
+ after, err := unmarshaler(data, resolvers)
require.NoError(t, err)
- require.Equal(t, op, rdt.after)
-}
-
-type roundTripper[OpT Operation] struct {
- Before OpT
- author identity.Interface
- after OpT
-}
-
-func (r *roundTripper[OpT]) MarshalJSON() ([]byte, error) {
- return json.Marshal(r.Before)
-}
-
-func (r *roundTripper[OpT]) UnmarshalJSON(data []byte) error {
- if err := json.Unmarshal(data, &r.after); err != nil {
- return err
- }
// Set the id from the serialized data
- r.after.setId(entity.DeriveId(data))
+ after.setId(entity.DeriveId(data))
// Set the author, as OperationPack would do
- r.after.setAuthor(r.author)
- return nil
+ after.setAuthor(rene)
+
+ require.Equal(t, op, after)
}