add comprehensive v2 examples and documentation
commit 402420e892dea1268b690a3c2a4dadca11932183 · parent 13b63c6f85
· browse this tree
Ximainth, 2025-10-19 10:20:48 UTC
Co-Authored-By: sketch <hello@sketch.dev> Change-ID: sb34fb4d228c4a67fk
diff --git a/v2/EXAMPLE.md b/v2/EXAMPLE.md new file mode 100644 index 0000000..a3b76cb --- /dev/null +++ b/v2/EXAMPLE.md @@ -0,0 +1,143 @@ +# Testmark v2 Examples + +This document demonstrates the key improvements in testmark v2. + +## Before: v1 Pain Points + +```go +// v1 required lots of boilerplate +func oldWay() { + doc, err := testmark.ReadFile("data.md") + if err != nil { + panic(err) + } + + // Required manual step! + doc.BuildDirIndex() + + // Manual patch accumulator setup + patches := &testmark.PatchAccumulator{} + + // Direct field access (error-prone) + for _, hunk := range doc.DataHunks { + fmt.Println(hunk.Name) // Accessing fields directly + if shouldUpdate { + patches.AppendPatch(testmark.Hunk{ + Name: hunk.Name, + Body: []byte("new content"), + }) + } + } + + // Complex patching + newDoc := testmark.Patch(doc, patches.Patches...) + + // Manual directory navigation + if doc.DirEnt != nil { + child := doc.DirEnt.Children["config"] + // null checks, manual iteration... + } +} +``` + +## After: v2 Clean API + +```go +// v2 is much cleaner and safer +func newWay() { + // Auto-indexing, no BuildDirIndex needed! + doc := testmark.MustReadFile("data.md") + + fmt.Printf("Loaded %d hunks\n", doc.Count()) + + // Safe iteration with clean accessors + for iter := doc.Hunks(); iter.Next(); { + hunk := iter.Hunk() + fmt.Printf("%s: %s\n", hunk.Name(), hunk.String()) + } + + // Clean patching + newHunk := testmark.NewHunkString("config/db", "json", `{"host": "new-host"}`) + updated := doc.Patch(newHunk) + + // Safe directory navigation + config := doc.Root().Child("config") + if config != nil { + for iter := config.Children(); iter.Next(); { + entry := iter.Entry() + fmt.Printf("Config %s: %s\n", entry.Name(), entry.Hunk().String()) + } + } + + // Easy serialization + fmt.Println(updated.String()) +} +``` + +## Key Improvements Summary + +### ✅ **Eliminated Boilerplate** +- No more `doc.BuildDirIndex()` - happens automatically +- No more `&testmark.PatchAccumulator{}` setup +- No more manual null checks and field access + +### ✅ **Private Fields = Safer Code** +```go +// v1: Error-prone direct access +doc.DataHunks[0].Name = "oops" // Could break things! + +// v2: Clean accessors only +hunk := doc.HunkByName("name") +name := hunk.Name() // Read-only, safe +``` + +### ✅ **Immutable Operations** +```go +// v2: Original documents never change +original := testmark.MustReadFile("data.md") +modified := original.Patch(newHunk) +// 'original' is unchanged, 'modified' is new +``` + +### ✅ **Safe Iterators** +```go +// v2: No direct slice access +for iter := doc.Hunks(); iter.Next(); { + hunk := iter.Hunk() // Safe, controlled access + // No risk of modifying internal state +} +``` + +### ✅ **Method Chaining** +```go +// v2: Fluent API +doc := testmark.MustReadFile("data.md") + .EnablePatching() + .Patches() + .Add(newHunk) +``` + +### ✅ **Contemporary Patterns** +```go +// v2: Modern flag handling +var regenFlag = flag.Bool("testmark.regen", false, "regen fixtures") + +if testmark.ShouldRegen() { + // Handle regeneration +} +``` + +## Migration Guide + +| 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{}` | `doc.EnablePatching().Patches()` | +| Multiple package imports | Single `v2` import | +| Direct field access | Private fields + accessors | +| Mutable operations | Immutable (returns new docs) | + +The v2 API is designed to make the "right thing" easy and the "wrong thing" impossible through good API design.