chore(docs): convert parser_test.go + search_bench_test.go + add countSubstring helper

Drops `fmt` + `strings` imports from both test files.

Conversions in parser_test.go:
- strings.TrimSpace → Trim (1 site)
- strings.Builder → Builder (1 site)
- strings.Count → countSubstring() local helper (1 site; no core
  wrapper exists in dappco.re/go for strings.Count)
- fmt.Sprintf → Sprintf (5 sites)

Conversions in search_bench_test.go:
- strings.ToUpper → Upper (1 site)
- fmt.Sprintf → Sprintf (8 sites)

Adds countSubstring() helper to parser.go's package-local helper
section. Will be replaced by core.Count when the dappco.re/go bump
lands as a published tag.

All docs tests pass (and benchmarks compile).

Banned-imports: 13 → 9 (-4) for docs.

Refs Mantis #1316

Filed-by: hephaestus
Co-authored-by: Hephaestus <hephaestus@lthn.ai>
This commit is contained in:
user.email 2026-05-01 12:53:56 +01:00
parent 773beb5ad1
commit 4e41093582
3 changed files with 37 additions and 22 deletions

View file

@ -10,6 +10,25 @@ import (
"gopkg.in/yaml.v3"
)
// countSubstring returns the number of non-overlapping occurrences of substr
// in s. Equivalent of strings.Count without importing strings; no core
// wrapper exists in dappco.re/go.
func countSubstring(s, substr string) int {
if substr == "" {
return len(s) + 1
}
count := 0
start := 0
for {
idx := core.Index(s[start:], substr)
if idx < 0 {
return count
}
count++
start += idx + len(substr)
}
}
// repeat returns a string consisting of n copies of s. Equivalent of
// strings.Repeat without importing strings; no core wrapper exists in
// dappco.re/go.

View file

@ -3,8 +3,6 @@ package help
import (
. "dappco.re/go"
"fmt"
"strings"
)
func TestGenerateID_Good(t *T) {
@ -373,7 +371,7 @@ order: 99
AssertEqual(t, 99, topic.Order)
AssertEmpty(t, topic.Sections)
// Body after frontmatter is just a newline
AssertEqual(t, "", strings.TrimSpace(topic.Content))
AssertEqual(t, "", Trim(topic.Content))
}
func TestExtractFrontmatter_Bad_MalformedYAML(t *T) {
@ -478,8 +476,8 @@ Deepest heading level.
{5, "Level 5"},
{6, "Level 6"},
} {
AssertEqual(t, expected.level, sections[i].Level, fmt.Sprintf("section %d level", i))
AssertEqual(t, expected.title, sections[i].Title, fmt.Sprintf("section %d title", i))
AssertEqual(t, expected.level, sections[i].Level, Sprintf("section %d level", i))
AssertEqual(t, expected.title, sections[i].Title, Sprintf("section %d title", i))
}
// Verify content is associated with correct sections
@ -605,21 +603,21 @@ Content with Кириллица, 中文, العربية, and हिन्दी.
func TestParseTopic_Good_VeryLongDocument(t *T) {
// Build a document with 10,000+ lines
var b strings.Builder
var b Builder
b.WriteString("---\ntitle: Massive Document\ntags: [large, stress]\n---\n\n")
// Generate 100 sections, each with ~100 lines of content
for i := range 100 {
b.WriteString(fmt.Sprintf("## Section %d\n\n", i+1))
b.WriteString(Sprintf("## Section %d\n\n", i+1))
for j := range 100 {
b.WriteString(fmt.Sprintf("Line %d of section %d: Lorem ipsum dolor sit amet.\n", j+1, i+1))
b.WriteString(Sprintf("Line %d of section %d: Lorem ipsum dolor sit amet.\n", j+1, i+1))
}
b.WriteString("\n")
}
content := b.String()
lineCount := strings.Count(content, "\n")
lineCount := countSubstring(content, "\n")
AssertGreater(t, lineCount, 10000, "document should exceed 10K lines")
topic, err := ParseTopic("massive.md", []byte(content))

View file

@ -3,8 +3,6 @@ package help
import (
. "dappco.re/go"
"fmt"
"strings"
)
// titleCase capitalises the first letter of a string.
@ -13,7 +11,7 @@ func titleCase(s string) string {
if len(s) == 0 {
return s
}
return strings.ToUpper(s[:1]) + s[1:]
return Upper(s[:1]) + s[1:]
}
// buildLargeCatalog creates a search index with n topics for benchmarking.
@ -43,8 +41,8 @@ func buildLargeCatalog(n int) *searchIndex {
verb := verbs[i%len(verbs)]
adj := adjectives[i%len(adjectives)]
title := fmt.Sprintf("%s %s Guide %d", titleCase(adj), titleCase(subj), i)
content := fmt.Sprintf(
title := Sprintf("%s %s Guide %d", titleCase(adj), titleCase(subj), i)
content := Sprintf(
"This guide covers how to %s %s %s systems. "+
"It includes step-by-step instructions for setting up %s "+
"in both development and production environments. "+
@ -55,24 +53,24 @@ func buildLargeCatalog(n int) *searchIndex {
sections := []Section{
{
ID: fmt.Sprintf("overview-%d", i),
ID: Sprintf("overview-%d", i),
Title: "Overview",
Content: fmt.Sprintf("An overview of %s %s patterns and best practices.", adj, subj),
Content: Sprintf("An overview of %s %s patterns and best practices.", adj, subj),
},
{
ID: fmt.Sprintf("setup-%d", i),
Title: fmt.Sprintf("%s Setup", titleCase(subj)),
Content: fmt.Sprintf("Detailed setup instructions for %s. Run the %s command to begin.", subj, verb),
ID: Sprintf("setup-%d", i),
Title: Sprintf("%s Setup", titleCase(subj)),
Content: Sprintf("Detailed setup instructions for %s. Run the %s command to begin.", subj, verb),
},
{
ID: fmt.Sprintf("troubleshooting-%d", i),
ID: Sprintf("troubleshooting-%d", i),
Title: "Troubleshooting",
Content: fmt.Sprintf("Common issues when working with %s and how to resolve them.", subj),
Content: Sprintf("Common issues when working with %s and how to resolve them.", subj),
},
}
idx.Add(&Topic{
ID: fmt.Sprintf("%s-%s-%d", adj, subj, i),
ID: Sprintf("%s-%s-%d", adj, subj, i),
Title: title,
Content: content,
Sections: sections,