EXAMPLE.md
Testmark v2 Examples๐
This document demonstrates the key improvements in testmark v2.
Before: v1 Pain Points๐
// 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๐
// 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๐
// 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๐
// v2: Original documents never change
original := testmark.MustReadFile("data.md")
modified := original.Patch(newHunk)
// 'original' is unchanged, 'modified' is new
โ Safe Iterators๐
// 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๐
// v2: Fluent API
doc := testmark.MustReadFile("data.md")
.EnablePatching()
.Patches()
.Add(newHunk)
โ Contemporary Patterns๐
// 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.
v2/EXAMPLE.md ยท 3.7 KiB ยท 402420e892