package search
import (
"context"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
"sourcecraft.dev/bigbes/sr-ht-spec/core"
"sourcecraft.dev/bigbes/sr-ht-spec/doc"
"sourcecraft.dev/bigbes/sr-ht-spec/gitx"
)
// space is a shorthand for a valid SpaceRef in tests.
func space(t *testing.T, s string) core.SpaceRef {
t.Helper()
sp, err := core.ParseSpaceRef(s)
require.NoError(t, err)
return sp
}
// corpus is a space's worth of documents, built in memory. No repository, no
// checkout: doc.FromDocuments is the seam that takes a document set directly,
// and gitx.Document is exactly what a tree walk yields.
type corpus struct {
Space core.SpaceRef
Rev string
docs []gitx.Document
}
func newCorpus(t *testing.T, ref, rev string) *corpus {
t.Helper()
return &corpus{Space: space(t, ref), Rev: rev}
}
func (c *corpus) add(path, body string) *corpus {
c.docs = append(c.docs, gitx.Document{Path: path, Data: []byte(body)})
return c
}
// extract builds the archive and projects it into indexable documents, which is
// the whole of what service/ will do between a tree walk and a rebuild.
func (c *corpus) extract(t *testing.T) []Document {
t.Helper()
arc := doc.FromDocuments(c.Space, c.Rev, c.docs)
docs, err := Extract(arc, Bodies(c.docs))
require.NoError(t, err)
return docs
}
// openIndex opens an empty index in a temp dir, closed at the end of the test.
func openIndex(t *testing.T) *Index {
t.Helper()
idx, err := Open(filepath.Join(t.TempDir(), "spec.bleve"))
require.NoError(t, err)
t.Cleanup(func() { require.NoError(t, idx.Close()) })
return idx
}
// indexCorpus opens an index and rebuilds every corpus into it.
func indexCorpus(t *testing.T, corpora ...*corpus) *Index {
t.Helper()
idx := openIndex(t)
for _, c := range corpora {
_, err := idx.RebuildSpace(context.Background(), c.Space, c.extract(t))
require.NoError(t, err)
}
return idx
}
// hitIDs is the ordered list of document ids a search returned.
func hitIDs(t *testing.T, idx *Index, q Query) []string {
t.Helper()
res, err := idx.Search(context.Background(), q)
require.NoError(t, err)
ids := make([]string, 0, len(res.Hits))
for _, h := range res.Hits {
ids = append(ids, h.ID)
}
return ids
}