Files
zenfeed/pkg/storage/feed/block/index/primary/primary_test.go
glidea 8b33df8a05 init
2025-04-19 15:50:26 +08:00

223 lines
5.0 KiB
Go

package primary
import (
"bytes"
"context"
"testing"
"time"
. "github.com/onsi/gomega"
"github.com/glidea/zenfeed/pkg/test"
)
func TestAdd(t *testing.T) {
RegisterTestingT(t)
type givenDetail struct {
existingItems map[uint64]FeedRef
}
type whenDetail struct {
id uint64
item FeedRef
}
type thenExpected struct {
items map[uint64]FeedRef
}
tests := []test.Case[givenDetail, whenDetail, thenExpected]{
{
Scenario: "Add Single Feed",
Given: "An index with existing item",
When: "Adding a single item",
Then: "Should store the item correctly",
GivenDetail: givenDetail{
existingItems: map[uint64]FeedRef{
0: {Chunk: 0, Offset: 0},
},
},
WhenDetail: whenDetail{
id: 1,
item: FeedRef{Chunk: 1, Offset: 100},
},
ThenExpected: thenExpected{
items: map[uint64]FeedRef{
0: {Chunk: 0, Offset: 0},
1: {Chunk: 1, Offset: 100},
},
},
},
{
Scenario: "Update Existing Feed",
Given: "An index with existing item",
When: "Adding item with same ID",
Then: "Should update the item reference",
GivenDetail: givenDetail{
existingItems: map[uint64]FeedRef{
1: {Chunk: 1, Offset: 100},
},
},
WhenDetail: whenDetail{
id: 1,
item: FeedRef{Chunk: 2, Offset: 200},
},
ThenExpected: thenExpected{
items: map[uint64]FeedRef{
1: {Chunk: 2, Offset: 200},
},
},
},
}
for _, tt := range tests {
t.Run(tt.Scenario, func(t *testing.T) {
// Given.
idx0, err := NewFactory().New("test", &Config{}, Dependencies{})
Expect(err).NotTo(HaveOccurred())
for id, item := range tt.GivenDetail.existingItems {
idx0.Add(context.Background(), id, item)
}
// When.
idx0.Add(context.Background(), tt.WhenDetail.id, tt.WhenDetail.item)
// Then.
primIdx := idx0.(*idx)
for id, expected := range tt.ThenExpected.items {
Expect(primIdx.m).To(HaveKey(id))
Expect(primIdx.m[id]).To(Equal(expected))
}
})
}
}
func TestSearch(t *testing.T) {
RegisterTestingT(t)
type givenDetail struct {
feeds map[uint64]FeedRef
}
type whenDetail struct {
searchID uint64
}
type thenExpected struct {
feedRef FeedRef
found bool
}
tests := []test.Case[givenDetail, whenDetail, thenExpected]{
{
Scenario: "Search Existing Feed",
Given: "An index with feeds",
When: "Searching for existing ID",
Then: "Should return correct FeedRef",
GivenDetail: givenDetail{
feeds: map[uint64]FeedRef{
1: {Chunk: 1, Offset: 100},
2: {Chunk: 2, Offset: 200},
},
},
WhenDetail: whenDetail{
searchID: 1,
},
ThenExpected: thenExpected{
feedRef: FeedRef{Chunk: 1, Offset: 100},
found: true,
},
},
{
Scenario: "Search Non-Existing Feed",
Given: "An index with feeds",
When: "Searching for non-existing ID",
Then: "Should return empty FeedRef",
GivenDetail: givenDetail{
feeds: map[uint64]FeedRef{
1: {Chunk: 1, Offset: 100},
},
},
WhenDetail: whenDetail{
searchID: 2,
},
ThenExpected: thenExpected{
feedRef: FeedRef{},
found: false,
},
},
}
for _, tt := range tests {
t.Run(tt.Scenario, func(t *testing.T) {
// Given.
idx, err := NewFactory().New("test", &Config{}, Dependencies{})
Expect(err).NotTo(HaveOccurred())
for id, item := range tt.GivenDetail.feeds {
idx.Add(context.Background(), id, item)
}
// When.
result, ok := idx.Search(context.Background(), tt.WhenDetail.searchID)
// Then.
Expect(result).To(Equal(tt.ThenExpected.feedRef))
Expect(ok).To(Equal(tt.ThenExpected.found))
})
}
}
func TestEncodeDecode(t *testing.T) {
RegisterTestingT(t)
type givenDetail struct {
feeds map[uint64]FeedRef
}
type whenDetail struct{}
type thenExpected struct {
success bool
}
tests := []test.Case[givenDetail, whenDetail, thenExpected]{
{
Scenario: "Encode and Decode Index with Data",
Given: "An index with feeds",
When: "Encoding and decoding",
Then: "Should restore all data correctly",
GivenDetail: givenDetail{
feeds: map[uint64]FeedRef{
1: {Chunk: 1, Offset: 100, Time: time.Now()},
2: {Chunk: 2, Offset: 200, Time: time.Now()},
},
},
WhenDetail: whenDetail{},
ThenExpected: thenExpected{
success: true,
},
},
}
for _, tt := range tests {
t.Run(tt.Scenario, func(t *testing.T) {
// Given.
original, err := NewFactory().New("test", &Config{}, Dependencies{})
Expect(err).NotTo(HaveOccurred())
for id, item := range tt.GivenDetail.feeds {
original.Add(context.Background(), id, item)
}
// When.
var buf bytes.Buffer
err = original.EncodeTo(context.Background(), &buf)
Expect(err).NotTo(HaveOccurred())
decoded, err := NewFactory().New("test", &Config{}, Dependencies{})
Expect(err).NotTo(HaveOccurred())
err = decoded.DecodeFrom(context.Background(), &buf)
Expect(err).NotTo(HaveOccurred())
// Then.
origIdx := original.(*idx)
decodedIdx := decoded.(*idx)
Expect(decodedIdx.m).To(Equal(origIdx.m))
})
}
}