package godocs
import (
"strings"
"testing"
"github.com/PuerkitoBio/goquery"
)
const testPackageHTML = `
runtime - pkg.go.dev
Package runtime defines conversions between generic types and structs to map query strings to struct objects.
This is additional documentation text for the package.
func DecodeInto(d Decoder, data []byte, into Object) error
DecodeInto is a helper function that decodes the given data into the provided object.
type Codec struct {
Encoder Encoder
Decoder Decoder
}
Codec is a struct that holds an encoder and decoder.
func (c *Codec) Encode(obj Object) ([]byte, error)
Encode encodes the given object.
const (
ContentTypeJSON = "application/json"
ContentTypeYAML = "application/yaml"
)
Content types for different formats.
var DefaultScheme = NewScheme()
DefaultScheme is the default scheme used for encoding/decoding.
`
const testSearchHTML = `
Package runtime defines conversions between generic types and structs.
Package query implements encoding of structs into URL query parameters.
`
func TestParsePackagePage(t *testing.T) {
parser := NewParser()
pkg, err := parser.ParsePackagePage(testPackageHTML, "https://pkg.go.dev/k8s.io/apimachinery/pkg/runtime")
if err != nil {
t.Fatalf("ParsePackagePage failed: %v", err)
}
if pkg.Name != "runtime" {
t.Errorf("Expected name 'runtime', got '%s'", pkg.Name)
}
if pkg.ImportPath != "k8s.io/apimachinery/pkg/runtime" {
t.Errorf("Expected import path 'k8s.io/apimachinery/pkg/runtime', got '%s'", pkg.ImportPath)
}
if pkg.Version != "v0.35.1" {
t.Errorf("Expected version 'v0.35.1', got '%s'", pkg.Version)
}
if pkg.ImportedBy != 144729 {
t.Errorf("Expected imported by 144729, got %d", pkg.ImportedBy)
}
if pkg.Synopsis == "" {
t.Error("Expected non-empty synopsis")
}
if len(pkg.Functions) == 0 {
t.Error("Expected at least one function")
}
if len(pkg.Types) == 0 {
t.Error("Expected at least one type")
}
if len(pkg.Constants) == 0 {
t.Error("Expected at least one constant")
}
if len(pkg.Variables) == 0 {
t.Error("Expected at least one variable")
}
}
func TestParseSearchResults(t *testing.T) {
parser := NewParser()
results, err := parser.ParseSearchResults(testSearchHTML)
if err != nil {
t.Fatalf("ParseSearchResults failed: %v", err)
}
if len(results) < 2 {
t.Fatalf("Expected at least 2 results, got %d", len(results))
}
first := results[0]
if first.Synopsis == "" {
t.Error("Expected non-empty synopsis")
}
if first.Path == "" {
t.Error("Expected non-empty path")
}
if first.URL == "" {
t.Error("Expected non-empty URL")
}
}
func TestIsExported(t *testing.T) {
tests := []struct {
name string
expected bool
}{
{"Exported", true},
{"unexported", false},
{"", false},
{"CamelCase", true},
{"camelCase", false},
{"X", true},
{"x", false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := isExported(tt.name); got != tt.expected {
t.Errorf("isExported(%q) = %v, want %v", tt.name, got, tt.expected)
}
})
}
}
func TestCleanWhitespace(t *testing.T) {
tests := []struct {
input string
expected string
}{
{" hello world ", "hello world"},
{"single", "single"},
{"multiple spaces here", "multiple spaces here"},
{"\n\ttabs\t\n", "tabs"},
}
for _, tt := range tests {
t.Run(tt.input, func(t *testing.T) {
if got := cleanWhitespace(tt.input); got != tt.expected {
t.Errorf("cleanWhitespace(%q) = %q, want %q", tt.input, got, tt.expected)
}
})
}
}
func TestParseCount(t *testing.T) {
tests := []struct {
input string
expected int
}{
{"144729", 144729},
{"5,111", 5111},
{"0", 0},
{"1,234,567", 1234567},
{"abc", 0},
{"", 0},
}
for _, tt := range tests {
t.Run(tt.input, func(t *testing.T) {
if got := parseCount(tt.input); got != tt.expected {
t.Errorf("parseCount(%q) = %d, want %d", tt.input, got, tt.expected)
}
})
}
}
func TestExtractImportPath(t *testing.T) {
parser := NewParser()
tests := []struct {
html string
url string
expected string
}{
{
html: ``,
url: "https://pkg.go.dev/k8s.io/apimachinery/pkg/runtime",
expected: "k8s.io/apimachinery/pkg/runtime",
},
{
html: ``,
url: "https://pkg.go.dev/github.com/user/repo@v1.0.0",
expected: "github.com/user/repo",
},
}
for _, tt := range tests {
t.Run(tt.expected, func(t *testing.T) {
doc, err := goquery.NewDocumentFromReader(strings.NewReader(tt.html))
if err != nil {
t.Fatalf("Failed to parse HTML: %v", err)
}
got := parser.extractImportPath(doc, tt.url)
if got != tt.expected {
t.Errorf("extractImportPath() = %q, want %q", got, tt.expected)
}
})
}
}