package rustdocs
import (
"strings"
"testing"
"github.com/PuerkitoBio/goquery"
)
const testStructPageHTML = `
pub struct Mask<T, const N: usize>()
A SIMD vector mask for N elements.
Implementations
Tests the value of the specified element.
`
const testSearchHTML = `
`
const testCratePageHTML = `
Crate serde
1.0.0
A framework for serializing and deserializing Rust data structures.
Modules
deDeserialize implementation.
Structs
SerializerA structure for serializing Rust values.
Enums
ErrorErrors during serialization.
`
func TestParseItemPage(t *testing.T) {
parser := NewParser()
symbol, err := parser.ParseItemPage(testStructPageHTML, "https://docs.rs/std/simd/struct.Mask.html")
if err != nil {
t.Fatalf("ParseItemPage failed: %v", err)
}
if symbol.Name != "Mask" {
t.Errorf("Expected name 'Mask', got '%s'", symbol.Name)
}
if symbol.Kind != ItemKindStruct {
t.Errorf("Expected kind 'struct', got '%s'", symbol.Kind)
}
if symbol.Doc == "" {
t.Error("Expected non-empty doc")
}
if !strings.Contains(symbol.Signature, "struct Mask") {
t.Errorf("Expected signature to contain 'struct Mask', got '%s'", symbol.Signature)
}
}
func TestParseSearchResults(t *testing.T) {
parser := NewParser()
results, err := parser.ParseSearchResults(testSearchHTML)
if err != nil {
t.Fatalf("ParseSearchResults failed: %v", err)
}
if len(results) < 3 {
t.Fatalf("Expected at least 3 results, got %d", len(results))
}
method := results[0]
if method.Kind != "fn" {
t.Errorf("Expected kind 'fn' for method, got '%s'", method.Kind)
}
if method.Description == "" {
t.Error("Expected non-empty description")
}
structResult := results[1]
if structResult.Kind != "struct" {
t.Errorf("Expected kind 'struct', got '%s'", structResult.Kind)
}
fnResult := results[2]
if fnResult.Kind != "fn" {
t.Errorf("Expected kind 'fn', got '%s'", fnResult.Kind)
}
}
func TestParseCratePage(t *testing.T) {
parser := NewParser()
crate, err := parser.ParseCratePage(testCratePageHTML, "https://docs.rs/serde")
if err != nil {
t.Fatalf("ParseCratePage failed: %v", err)
}
if crate.Name == "" {
t.Error("Expected non-empty name")
}
if crate.Description == "" {
t.Error("Expected non-empty description")
}
}
func TestExtractKindFromClasses(t *testing.T) {
tests := []struct {
classes string
expected string
}{
{"result-struct", "struct"},
{"result-enum", "enum"},
{"result-trait", "trait"},
{"result-fn", "fn"},
{"result-macro", "macro"},
{"result-const", "const"},
{"result-static", "static"},
{"result-mod", "mod"},
{"result-method", "fn"},
{"result-externcrate", "mod"},
{"unknown-class", ""},
}
for _, tt := range tests {
t.Run(tt.classes, func(t *testing.T) {
got := extractKindFromClasses(tt.classes)
if got != tt.expected {
t.Errorf("extractKindFromClasses(%q) = %q, want %q", tt.classes, got, tt.expected)
}
})
}
}
func TestResolveURL(t *testing.T) {
tests := []struct {
base string
href string
expected string
}{
{"https://docs.rs", "/serde/struct.Serializer.html", "https://docs.rs/serde/struct.Serializer.html"},
{"https://docs.rs", "https://example.com/page", "https://example.com/page"},
}
for _, tt := range tests {
t.Run(tt.href, func(t *testing.T) {
got := resolveURL(tt.base, tt.href)
if got != tt.expected {
t.Errorf("resolveURL(%q, %q) = %q, want %q", tt.base, tt.href, got, tt.expected)
}
})
}
}
func TestCleanText(t *testing.T) {
tests := []struct {
input string
expected string
}{
{" hello world ", "hello world"},
{"single", "single"},
{"\n\ttabs\t\n", "tabs"},
}
for _, tt := range tests {
t.Run(tt.input, func(t *testing.T) {
if got := cleanText(tt.input); got != tt.expected {
t.Errorf("cleanText(%q) = %q, want %q", tt.input, got, tt.expected)
}
})
}
}
func TestExtractItemPath(t *testing.T) {
parser := NewParser()
html := ``
doc, err := goquery.NewDocumentFromReader(strings.NewReader(html))
if err != nil {
t.Fatalf("Failed to parse HTML: %v", err)
}
got := parser.extractItemPath(doc, "https://docs.rs/std/simd/struct.Mask.html")
if !strings.Contains(got, "std") || !strings.Contains(got, "simd") {
t.Errorf("extractItemPath() = %q, expected to contain std and simd", got)
}
}
func TestExtractMethods(t *testing.T) {
parser := NewParser()
doc, err := goquery.NewDocumentFromReader(strings.NewReader(testStructPageHTML))
if err != nil {
t.Fatalf("Failed to parse HTML: %v", err)
}
methods := parser.ExtractMethods(doc)
if len(methods) == 0 {
t.Error("Expected at least one method")
return
}
if methods[0].Name == "" {
t.Error("Expected non-empty method name")
}
}