1
0
Fork 0
hugo/identity/identity_test.go

212 lines
4.8 KiB
Go

// Copyright 2024 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package identity_test
import (
"fmt"
"testing"
qt "github.com/frankban/quicktest"
"github.com/gohugoio/hugo/identity"
"github.com/gohugoio/hugo/identity/identitytesting"
)
func BenchmarkIdentityManager(b *testing.B) {
createIds := func(num int) []identity.Identity {
ids := make([]identity.Identity, num)
for i := 0; i < num; i++ {
name := fmt.Sprintf("id%d", i)
ids[i] = &testIdentity{base: name, name: name}
}
return ids
}
b.Run("identity.NewManager", func(b *testing.B) {
for i := 0; i < b.N; i++ {
m := identity.NewManager("")
if m == nil {
b.Fatal("manager is nil")
}
}
})
b.Run("Add unique", func(b *testing.B) {
ids := createIds(b.N)
im := identity.NewManager("")
b.ResetTimer()
for i := 0; i < b.N; i++ {
im.AddIdentity(ids[i])
}
b.StopTimer()
})
b.Run("Add duplicates", func(b *testing.B) {
id := &testIdentity{base: "a", name: "b"}
im := identity.NewManager("")
b.ResetTimer()
for i := 0; i < b.N; i++ {
im.AddIdentity(id)
}
b.StopTimer()
})
b.Run("Nop StringIdentity const", func(b *testing.B) {
const id = identity.StringIdentity("test")
for i := 0; i < b.N; i++ {
identity.NopManager.AddIdentity(id)
}
})
b.Run("Nop StringIdentity const other package", func(b *testing.B) {
for i := 0; i < b.N; i++ {
identity.NopManager.AddIdentity(identitytesting.TestIdentity)
}
})
b.Run("Nop StringIdentity var", func(b *testing.B) {
id := identity.StringIdentity("test")
for i := 0; i < b.N; i++ {
identity.NopManager.AddIdentity(id)
}
})
b.Run("Nop pointer identity", func(b *testing.B) {
id := &testIdentity{base: "a", name: "b"}
for i := 0; i < b.N; i++ {
identity.NopManager.AddIdentity(id)
}
})
b.Run("Nop Anonymous", func(b *testing.B) {
for i := 0; i < b.N; i++ {
identity.NopManager.AddIdentity(identity.Anonymous)
}
})
}
func BenchmarkIsNotDependent(b *testing.B) {
runBench := func(b *testing.B, id1, id2 identity.Identity) {
for i := 0; i < b.N; i++ {
isNotDependent(id1, id2)
}
}
newNestedManager := func(depth, count int) identity.Manager {
m1 := identity.NewManager("")
for i := 0; i < depth; i++ {
m2 := identity.NewManager("")
m1.AddIdentity(m2)
for j := 0; j < count; j++ {
id := fmt.Sprintf("id%d", j)
m2.AddIdentity(&testIdentity{id, id, "", ""})
}
m1 = m2
}
return m1
}
type depthCount struct {
depth int
count int
}
for _, dc := range []depthCount{{10, 5}} {
b.Run(fmt.Sprintf("Nested not found %d %d", dc.depth, dc.count), func(b *testing.B) {
im := newNestedManager(dc.depth, dc.count)
id1 := identity.StringIdentity("idnotfound")
b.ResetTimer()
runBench(b, im, id1)
})
}
}
func TestIdentityManager(t *testing.T) {
c := qt.New(t)
newNestedManager := func() identity.Manager {
m1 := identity.NewManager("")
m2 := identity.NewManager("")
m3 := identity.NewManager("")
m1.AddIdentity(
testIdentity{"base", "id1", "", "pe1"},
testIdentity{"base2", "id2", "eq1", ""},
m2,
m3,
)
m2.AddIdentity(testIdentity{"base4", "id4", "", ""})
return m1
}
c.Run("Anonymous", func(c *qt.C) {
im := newNestedManager()
c.Assert(im.GetIdentity(), qt.Equals, identity.Anonymous)
im.AddIdentity(identity.Anonymous)
c.Assert(isNotDependent(identity.Anonymous, identity.Anonymous), qt.IsTrue)
})
c.Run("GenghisKhan", func(c *qt.C) {
c.Assert(isNotDependent(identity.GenghisKhan, identity.GenghisKhan), qt.IsTrue)
})
}
type testIdentity struct {
base string
name string
idEq string
idProbablyEq string
}
func (id testIdentity) Eq(other any) bool {
ot, ok := other.(testIdentity)
if !ok {
return false
}
if ot.idEq == "" || id.idEq == "" {
return false
}
return ot.idEq == id.idEq
}
func (id testIdentity) IdentifierBase() string {
return id.base
}
func (id testIdentity) Name() string {
return id.name
}
func (id testIdentity) ProbablyEq(other any) bool {
ot, ok := other.(testIdentity)
if !ok {
return false
}
if ot.idProbablyEq == "" || id.idProbablyEq == "" {
return false
}
return ot.idProbablyEq == id.idProbablyEq
}
func isNotDependent(a, b identity.Identity) bool {
f := identity.NewFinder(identity.FinderConfig{})
r := f.Contains(b, a, -1)
return r == 0
}