doctest_test.go
package testmark_test
import (
"os"
"regexp"
"strings"
"testing"
testmark "github.com/warpfork/go-testmark/v2"
)
func TestDocTestFunctionality(t *testing.T) {
// Test the DocTest struct creation
doctest := testmark.DefaultDocTest()
if doctest == nil {
t.Fatal("DefaultDocTest returned nil")
}
if doctest.PackageTemplate == "" {
t.Error("PackageTemplate should not be empty")
}
if len(doctest.SkipPatterns) == 0 {
t.Error("Should have default skip patterns")
}
// Test code identification
tests := []struct {
lang string
code string
expected bool
}{
{"go", "fmt.Println(\"hello\")", true},
{"golang", "package main", true},
{"", "package main\nfunc main() {}", true},
{"", "testmark.NewHunk(\"test\", \"\", \"content\")", true},
{"", "fmt := \"hello\"", true},
{"python", "print('hello')", false},
{"shell", "echo hello", false},
}
for _, tt := range tests {
if got := doctest.IsGoCode(tt.lang, tt.code); got != tt.expected {
t.Errorf("isGoCode(%q, %q) = %v, want %v", tt.lang, tt.code, got, tt.expected)
}
}
}
func TestSkipPatterns(t *testing.T) {
doctest := testmark.DefaultDocTest()
// Test skip patterns
tests := []struct {
code string
expected bool
}{
{"// skip this code", true},
{"// TODO: implement this", true},
{"func TestSomething(t *testing.T) {}", true},
{"func ExampleUsage() {}", true},
{"fmt.Println(\"hello\")", false},
}
for _, tt := range tests {
if got := doctest.ShouldSkip(tt.code); got != tt.expected {
t.Errorf("ShouldSkip(%q) = %v, want %v", tt.code, got, tt.expected)
}
}
}
func TestCodeBlockExtraction(t *testing.T) {
doctest := testmark.DefaultDocTest()
markdown := `# Example
Here's some Go code:
` + "```go\npackage main\nfunc main() { fmt.Println(\"hello\") }\n```" + `
And some other code:
` + "```python\nprint('hello')\n```" + `
And another Go block:
` + "```\nfmt.Println(\"implicit go\")\n```" + `
`
blocks := doctest.ExtractGoCodeBlocks(markdown)
if len(blocks) != 2 {
t.Errorf("expected 2 Go code blocks, got %d", len(blocks))
}
expected := []string{
"package main\nfunc main() { fmt.Println(\"hello\") }",
"fmt.Println(\"implicit go\")",
}
for i, block := range blocks {
if i >= len(expected) {
break
}
if strings.TrimSpace(block) != expected[i] {
t.Errorf("block %d:\nexpected: %q\ngot: %q", i, expected[i], strings.TrimSpace(block))
}
}
}
func TestSyntaxValidation(t *testing.T) {
doctest := testmark.DefaultDocTest()
tests := []struct {
code string
valid bool
}{
{"package main\nfunc main() {}", true},
{"fmt.Println(\"hello\")", false}, // incomplete
{"package main\nfunc main() { invalid syntax", false},
{"var x = 42", false}, // incomplete
}
for _, tt := range tests {
if got := doctest.IsValidGoSyntax(tt.code); got != tt.valid {
t.Errorf("IsValidGoSyntax(%q) = %v, want %v", tt.code, got, tt.valid)
}
}
}
func TestCodeWrapping(t *testing.T) {
doctest := testmark.DefaultDocTest()
code := "fmt.Println(\"hello\")"
wrapped := doctest.WrapCode(code)
if !strings.Contains(wrapped, "package main") {
t.Error("wrapped code should contain package declaration")
}
if !strings.Contains(wrapped, "func main()") {
t.Error("wrapped code should contain main function")
}
if !strings.Contains(wrapped, "fmt.Println") {
t.Error("wrapped code should contain original code")
}
// Test that wrapped code is valid
if !doctest.IsValidGoSyntax(wrapped) {
t.Errorf("wrapped code should be valid Go:\n%s", wrapped)
}
}
func TestConvenienceFunctions(t *testing.T) {
// We can't easily test the actual file operations without creating temp files,
// but we can test that the functions exist and don't panic when called with empty FS
emptyFS := os.DirFS("/nonexistent")
defer func() {
if r := recover(); r != nil {
// Expected to fail due to nonexistent directory, but shouldn't panic
t.Log("Expected failure for nonexistent directory")
}
}()
// These should not panic, even with empty/invalid FS
t.Run("TestReadmeExamples", func(t *testing.T) {
// This will likely fail to find files, but shouldn't panic
testmark.TestReadmeExamples(t, emptyFS)
})
}
// Test that we can create custom DocTest configurations
func TestCustomDocTest(t *testing.T) {
doctest := &testmark.DocTest{
PackageTemplate: "custom template",
ImportTemplate: "custom imports",
TestTimeout: "60s",
SkipPatterns: []*regexp.Regexp{
regexp.MustCompile("CUSTOM_SKIP"),
},
}
if doctest.PackageTemplate != "custom template" {
t.Error("custom package template not set")
}
if !doctest.ShouldSkip("// CUSTOM_SKIP this code") {
t.Error("custom skip pattern not working")
}
}
v2/doctest_test.go · 4.6 KiB · 07c6e4c9e7