// Copyright Earl Warren // Copyright Loïc Dachary // SPDX-License-Identifier: MIT package generic import ( "context" "testing" "code.forgejo.org/f3/gof3/v3/f3" "code.forgejo.org/f3/gof3/v3/id" "code.forgejo.org/f3/gof3/v3/kind" "code.forgejo.org/f3/gof3/v3/path" "github.com/stretchr/testify/assert" ) type referenceFormat struct { f3.Common R *f3.Reference } func (o *referenceFormat) Clone() f3.Interface { clone := &referenceFormat{} *clone = *o return clone } func (o *referenceFormat) GetReferences() f3.References { references := o.Common.GetReferences() if o.R != nil { references = append(references, o.R) } return references } type referencesNodeDriver struct { NullDriver f referenceFormat } func (o *referencesNodeDriver) GetIDFromName(ctx context.Context, name string) id.NodeID { return id.NilID } func (o *referencesNodeDriver) Get(context.Context) bool { return true } func (o *referencesNodeDriver) NewFormat() f3.Interface { return &referenceFormat{} } func (o *referencesNodeDriver) ToFormat() f3.Interface { return &o.f } func (o *referencesNodeDriver) FromFormat(f f3.Interface) { o.f = *f.(*referenceFormat) } func newReferencesNodeDriver() NodeDriverInterface { return &referencesNodeDriver{} } type testTreeReferencesDriver struct { NullTreeDriver } func newTestTreeReferencesDriver() TreeDriverInterface { return &testTreeReferencesDriver{} } func (o *testTreeReferencesDriver) Factory(ctx context.Context, kind kind.Kind) NodeDriverInterface { d := newReferencesNodeDriver() d.SetTreeDriver(o) return d } var kindTestNodeReferences = kind.Kind("references") type testNodeReferences struct { testNode } func newTestTreeReferences() TreeInterface { tree := &testTree{} tree.Init(tree, newTestOptions()) tree.SetDriver(newTestTreeReferencesDriver()) tree.Register(kindTestNodeReferences, func(ctx context.Context, kind kind.Kind) NodeInterface { node := &testNodeReferences{} return node.Init(node) }) return tree } func TestTreeCollectReferences(t *testing.T) { tree := newTestTreeReferences() root := tree.Factory(context.Background(), kindTestNodeReferences) tree.SetRoot(root) one := tree.Factory(context.Background(), kindTestNodeReferences) one.FromFormat(&referenceFormat{R: f3.NewReference("/somewhere")}) one.SetID(id.NewNodeID("one")) root.SetChild(one) // the second node that has the same reference is here to ensure // they are deduplicated two := tree.Factory(context.Background(), kindTestNodeReferences) two.FromFormat(&referenceFormat{R: f3.NewReference("/somewhere")}) two.SetID(id.NewNodeID("two")) root.SetChild(two) references := TreeCollectReferences(context.Background(), tree, path.NewPathFromString(NewElementNode, "/")) assert.Len(t, references, 1) assert.EqualValues(t, "/somewhere", references[0].String()) } func TestRemapReferences(t *testing.T) { tree := newTestTreeReferences() root := tree.Factory(context.Background(), kindTestNodeReferences) tree.SetRoot(root) one := tree.Factory(context.Background(), kindTestNodeReferences) one.SetID(id.NewNodeID("one")) one.SetMappedID(id.NewNodeID("remappedone")) one.SetParent(root) root.SetChild(one) two := tree.Factory(context.Background(), kindTestNodeReferences) two.FromFormat(&referenceFormat{R: f3.NewReference("/one")}) two.SetID(id.NewNodeID("two")) two.SetMappedID(id.NewNodeID("two")) two.SetParent(root) root.SetChild(two) { f := two.ToFormat() RemapReferences(context.Background(), two, f) r := f.GetReferences() if assert.Len(t, r, 1) { assert.Equal(t, "/remappedone", r[0].Get()) } } three := tree.Factory(context.Background(), kindTestNodeReferences) three.FromFormat(&referenceFormat{R: f3.NewReference("../../one")}) three.SetID(id.NewNodeID("three")) three.SetMappedID(id.NewNodeID("three")) three.SetParent(two) two.SetChild(three) { f := three.ToFormat() RemapReferences(context.Background(), three, f) r := f.GetReferences() if assert.Len(t, r, 1) { assert.Equal(t, "../../remappedone", r[0].Get()) } } assert.Panics(t, func() { RemapReferences(context.Background(), three, &referenceFormat{R: f3.NewReference("./one")}) }) }