Files
Devour/cmd/ask_test.go
Tomas Dvorak 898a3c303f update
2026-02-24 10:33:59 +01:00

145 lines
4.1 KiB
Go

package cmd
import (
"strings"
"testing"
"github.com/yourorg/devour/internal/scraper"
)
func TestDeriveSearchTerms(t *testing.T) {
terms := deriveSearchTerms("go", "how to regex match http path")
if len(terms) == 0 {
t.Fatal("expected at least one derived search term")
}
joined := strings.Join(terms, ",")
if !strings.Contains(joined, "regexp") {
t.Fatalf("expected regexp term in %v", terms)
}
if !strings.Contains(joined, "net/http") {
t.Fatalf("expected net/http term in %v", terms)
}
}
func TestScoreDocument(t *testing.T) {
query := "regex match in go"
docTitleMatch := &scraper.Document{
Title: "Package regexp",
Content: "Use MustCompile and MatchString to match values.",
Type: "go-package",
URL: "https://pkg.go.dev/regexp",
}
docNoMatch := &scraper.Document{
Title: "Package archive/tar",
Content: "Read and write tar archives.",
Type: "go-package",
URL: "https://pkg.go.dev/archive/tar",
}
if scoreDocument(query, docTitleMatch) <= scoreDocument(query, docNoMatch) {
t.Fatal("expected regex-related document to have a higher score")
}
}
func TestExtractRecommendedAPI(t *testing.T) {
docs := []rankedDoc{
{
doc: &scraper.Document{
Title: "regexp.func MustCompile ¶",
URL: "https://pkg.go.dev/regexp",
Content: "re := regexp.MustCompile(`\\\\d+`)\nif re.MatchString(input) { fmt.Println(\"ok\") }",
},
},
}
apis := extractRecommendedAPI(docs)
if len(apis) == 0 {
t.Fatal("expected API extraction to return at least one call")
}
}
func TestExtractSnippet(t *testing.T) {
content := "The regexp package implements regular expression search. Use MustCompile for fixed patterns."
snippet := extractSnippet(content, []string{"regexp"})
if snippet == "" {
t.Fatal("expected non-empty snippet")
}
if !strings.Contains(strings.ToLower(snippet), "regexp") {
t.Fatalf("snippet should mention regexp, got: %q", snippet)
}
}
func TestCandidateDocURLs_FrameworkFallbacks(t *testing.T) {
next, err := candidateDocURLs("nextjs", "routing")
if err != nil {
t.Fatalf("candidateDocURLs(nextjs) error: %v", err)
}
if len(next) < 2 {
t.Fatalf("expected fallback URLs for nextjs, got %v", next)
}
if next[0] != "https://nextjs.org/docs/app/building-your-application/routing" {
t.Fatalf("unexpected primary nextjs URL: %q", next[0])
}
remix, err := candidateDocURLs("remix", "routes")
if err != nil {
t.Fatalf("candidateDocURLs(remix) error: %v", err)
}
if len(remix) == 0 || remix[0] != "https://v2.remix.run/docs/file-conventions/routes" {
t.Fatalf("unexpected remix candidate URLs: %v", remix)
}
solid, err := candidateDocURLs("solid", "router")
if err != nil {
t.Fatalf("candidateDocURLs(solid) error: %v", err)
}
if len(solid) == 0 || !strings.Contains(solid[0], "github.com/solidjs/solid-docs") {
t.Fatalf("unexpected solid candidate URLs: %v", solid)
}
}
func TestPrimaryQueryTokenSkipsQuestionWords(t *testing.T) {
token := primaryQueryToken("what does routing do in remix")
if token == "" {
t.Fatal("expected non-empty token")
}
if token == "what" || token == "does" {
t.Fatalf("expected informative token, got %q", token)
}
}
func TestDeriveSearchTermsSolidRouting(t *testing.T) {
terms := deriveSearchTerms("solid", "how to do routing in solid")
joined := strings.Join(terms, ",")
if !strings.Contains(joined, "solid-router") {
t.Fatalf("expected solid-router term in %v", terms)
}
if strings.Contains(joined, "signals") {
t.Fatalf("did not expect signals default for routing question, got %v", terms)
}
}
func TestShouldFallbackToLive(t *testing.T) {
strong := []rankedDoc{
{
doc: &scraper.Document{Title: "Routing Guide", Content: "routing with file based routes", URL: "https://nextjs.org/docs/routing"},
score: 2.2,
},
}
if shouldFallbackToLive(strong, []string{"routing"}) {
t.Fatal("expected strong local match to skip live fallback")
}
weak := []rankedDoc{
{
doc: &scraper.Document{Title: "Misc", Content: "unrelated", URL: "https://example.com"},
score: 0.1,
},
}
if !shouldFallbackToLive(weak, []string{"routing"}) {
t.Fatal("expected weak local match to trigger live fallback")
}
}