// Copyright Earl Warren // Copyright Loïc Dachary // SPDX-License-Identifier: MIT package path import ( "fmt" "testing" "code.forgejo.org/f3/gof3/v3/f3" "code.forgejo.org/f3/gof3/v3/id" "code.forgejo.org/f3/gof3/v3/kind" "github.com/stretchr/testify/assert" ) type PathElementTest struct { id id.NodeID mapped id.NodeID kind kind.Kind name string } func NewPathElementTest() PathElement { return &PathElementTest{ id: id.NilID, mapped: id.NilID, } } func (o PathElementTest) GetID() id.NodeID { return o.id } func (o *PathElementTest) SetID(i id.NodeID) { o.id = i } func (o PathElementTest) GetMappedID() id.NodeID { return o.mapped } func (o *PathElementTest) SetMappedID(mapped id.NodeID) { o.mapped = mapped } func (o PathElementTest) GetKind() kind.Kind { return o.kind } func (o *PathElementTest) SetKind(kind kind.Kind) { o.kind = kind } type PathF3Test struct { f3.Common name string } func (o *PathF3Test) GetName() string { if o.name != "" { return o.name } return o.Common.GetName() } func (o PathElementTest) ToFormat() f3.Interface { return &PathF3Test{ Common: f3.NewCommon(o.GetID().String()), name: o.name, } } func TestNewPathFromString(t *testing.T) { for _, pathString := range []string{"", ".", "A/.."} { path := NewPathFromString(NewPathElementTest, pathString) assert.False(t, path.Empty(), path.String()) assert.Len(t, path, 1, path.String()) assert.EqualValues(t, ".", path.First().GetID()) } for _, pathString := range []string{"/", "/.", "/..", "/A/.."} { path := NewPathFromString(NewPathElementTest, pathString) assert.False(t, path.Empty(), path.String()) assert.Len(t, path, 1, path.String()) assert.EqualValues(t, kind.KindRoot, path.First().GetKind(), path.String()) assert.EqualValues(t, "", path.First().GetID()) } for _, pathString := range []string{"A", "A/.", "B/../A"} { path := NewPathFromString(NewPathElementTest, pathString) assert.False(t, path.Empty(), path.String()) assert.Len(t, path, 1, path.String()) assert.NotEqualValues(t, kind.KindRoot, path.First().GetKind(), path.String()) assert.EqualValues(t, "A", path.First().GetID()) } { pathString := "/A" path := NewPathFromString(NewPathElementTest, pathString) assert.False(t, path.Empty(), path.String()) assert.Len(t, path, 2, path.String()) assert.EqualValues(t, kind.KindRoot, path.First().GetKind(), path.String()) notRoot := path.RemoveFirst() assert.NotEqualValues(t, kind.KindRoot, notRoot.First().GetKind(), path.String()) assert.EqualValues(t, pathString, path.String(), path.String()) } { pathString := "A/B" path := NewPathFromString(NewPathElementTest, pathString) assert.False(t, path.Empty(), path.String()) assert.Len(t, path, 2, path.String()) assert.NotEqualValues(t, kind.KindRoot, path.First().GetKind(), path.String()) notRoot := path.RemoveFirst() assert.NotEqualValues(t, kind.KindRoot, notRoot.First().GetKind(), path.String()) assert.EqualValues(t, pathString, path.String(), path.String()) } { pathString := "../B" path := NewPathFromString(NewPathElementTest, pathString) assert.False(t, path.Empty(), path.String()) assert.Len(t, path, 2, path.String()) assert.NotEqualValues(t, kind.KindRoot, path.First().GetKind(), path.String()) notRoot := path.RemoveFirst() assert.NotEqualValues(t, kind.KindRoot, notRoot.First().GetKind(), path.String()) assert.EqualValues(t, pathString, path.String(), path.String()) } } func TestPathAbsoluteString(t *testing.T) { assert.Equal(t, "/c", PathAbsoluteString("/a/b", "/c/d/..")) assert.Equal(t, "/a/b/c", PathAbsoluteString("/a/b", "c")) assert.Equal(t, "/a/b/c", PathAbsoluteString("/a/./b", "c/d/..")) } func TestPathAbsolute(t *testing.T) { assert.Equal(t, "/a/b/c", PathAbsolute(NewPathElementTest, "/a/b", "c").String()) } func TestPathRelativeString(t *testing.T) { assert.Equal(t, "../c", PathRelativeString("/a/b/d", "/a/b/c")) assert.Panics(t, func() { PathRelativeString("/a/b/d", "") }) } func TestPathString(t *testing.T) { path := NewPathFromString(NewPathElementTest, "/a/b/c") assert.Equal(t, "/a/b/c", path.PathString().Join()) last, path := path.Pop() path = path.Append(NewPathElementTest()) path = path.Append(last) assert.Equal(t, "/a/b/nothing/c", path.PathString().Join()) } func TestPathReadable(t *testing.T) { path := NewPathFromString(NewPathElementTest, "/a/b/c") name := "N{AM}E" path.Last().(*PathElementTest).name = name assert.Equal(t, name, path.Last().ToFormat().GetName()) expected := fmt.Sprintf("/a/b/{%s/c}", replacer.Replace(name)) assert.Equal(t, expected, path.ReadablePathString().Join()) assert.Equal(t, expected, path.ReadableString()) path = NewPathFromString(NewPathElementTest, "") assert.Equal(t, "", path.ReadableString()) } func TestPathMappedString(t *testing.T) { path := NewPathFromString(NewPathElementTest, "/a/b") for _, node := range path.All() { node.SetMappedID(id.NewNodeID(node.GetID().String() + "M")) } assert.Equal(t, "M/aM/bM", path.PathMappedString().Join()) } func TestPathMethods(t *testing.T) { path := NewPathFromString(NewPathElementTest, "/a/b/c") assert.Equal(t, "/a/b/c", path.String()) assert.Equal(t, 4, path.Length()) assert.Len(t, path.All(), 4) assert.False(t, path.Empty()) first, path := path.PopFirst() assert.Equal(t, "", first.GetID().String()) assert.Equal(t, "a/b/c", path.String()) assert.Equal(t, "a", path.First().GetID().String()) assert.Equal(t, "c", path.Last().GetID().String()) firstRemoved := path.RemoveFirst() assert.Equal(t, "b/c", firstRemoved.String()) last, lastRemoved := path.Pop() assert.Equal(t, "c", last.GetID().String()) assert.Equal(t, "a/b", lastRemoved.String()) lastRemoved = path.RemoveLast() assert.Equal(t, "a/b", lastRemoved.String()) }