# Getting Started with testmark v2 ## Installation ```bash go get github.com/warpfork/go-testmark/v2@latest ``` For local testing with unreleased changes, add this to your `go.mod`: ```go require github.com/warpfork/go-testmark/v2 v0.0.0 replace github.com/warpfork/go-testmark/v2 => /path/to/local/go-testmark/v2 ``` ## Basic Usage ### 1. Core Functionality ```go package main import ( "fmt" testmark "github.com/warpfork/go-testmark/v2" ) func main() { // Parse automatically builds directory index doc := testmark.MustReadFile("example.md") // Clean API with type-safe generics hunk := testmark.NewHunk("config", "json", `{"host": "localhost"}`) // Immutable operations updated := doc.Patch(hunk) // Safe iteration iter := updated.Hunks() for hunk, ok := iter.Next(); ok; hunk, ok = iter.Next() { fmt.Printf("%s: %s\n", hunk.Name(), hunk.String()) } } ``` ### 2. Command Execution ```go package mytest import ( "testing" testmark "github.com/warpfork/go-testmark/v2" "github.com/warpfork/go-testmark/v2/testexec" ) func TestCommands(t *testing.T) { doc := testmark.MustReadFile("tests.md") // Test any system command testexec.Test(t, doc.Root().Child("echo-test")) // Test Go programs with smart package resolution testexec.TestGo(t, doc.Root().Child("go-test")) } ``` ### 3. Experimental Documentation Testing ```go package doctest import ( "os" "testing" "github.com/warpfork/go-testmark/v2/doctest" ) func TestDocumentation(t *testing.T) { // Test Go code snippets in markdown files tester := doctest.New() tester.TestReadme(t, os.DirFS(".")) } ``` ## Key Improvements from v1 ### ✅ **Eliminated Boilerplate** ```go // v1: Required manual steps doc, _ := testmark.ReadFile("test.md") doc.BuildDirIndex() // Manual! // v2: Automatic doc := testmark.MustReadFile("test.md") // Auto-indexed ``` ### ✅ **Type Safety** ```go // v1: Multiple functions, easy to get wrong testmark.Hunk{Name: "test", Body: []byte("content")} // v2: Generic, type-safe testmark.NewHunk("test", "", "content") // string testmark.NewHunk("test", "", []byte{1,2,3}) // []byte testmark.NewHunkFromReader("test", "", reader) // io.Reader ``` ### ✅ **Immutable Operations** ```go // v2: Original never changes original := testmark.MustReadFile("data.md") modified := original.Patch(newHunk) // 'original' is unchanged, 'modified' is new ``` ### ✅ **Modern Iterators** ```go // v2: Go-idiomatic (value, bool) pattern iter := doc.Hunks() for hunk, ok := iter.Next(); ok; hunk, ok = iter.Next() { fmt.Printf("Found: %s\n", hunk.Name()) } ``` ### ✅ **Clean Package Organization** - Core functionality: `github.com/warpfork/go-testmark/v2` - Command execution: `github.com/warpfork/go-testmark/v2/testexec` - Documentation testing: `github.com/warpfork/go-testmark/v2/doctest` (experimental) ## Migration from v1 The core concepts remain the same, but the API is much cleaner: | v1 Pattern | v2 Replacement | |------------|----------------| | `doc.BuildDirIndex()` | *automatic* | | `doc.DataHunks` | `doc.Hunks()` iterator | | `doc.HunksByName[name]` | `doc.HunkByName(name)` | | `doc.DirEnt.Children[name]` | `doc.Root().Child(name)` | | `&testmark.PatchAccumulator{}` | Built-in patching | | Direct field access | Private fields + accessors | | Mutable operations | Immutable (returns new docs) | ## Examples See the `/examples` directory for complete working examples of: - Basic document manipulation - Command execution testing - Go program testing - Documentation testing The v2 API makes the "right thing" easy and the "wrong thing" impossible through thoughtful design! 🚀