mirror of
https://github.com/Dvorinka/Devour.git
synced 2026-06-04 04:23:02 +00:00
145 lines
4.1 KiB
Go
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")
|
|
}
|
|
}
|