socle

config_test.go

package main

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"github.com/warpfork/go-testmark"
)

// TestLoadConfig drives loadConfig through the fixture cases in testdata/config.md.
// Each case is a pair of hunks: <case>/config.yaml (the input) and <case>/result
// (the expected outcome, either a repo listing or an error line).
// Run with -testmark.regen to regenerate the result hunks and review via git diff.
func TestLoadConfig(t *testing.T) {
	doc, err := testmark.ReadFile("testdata/config.md")
	if err != nil {
		t.Fatalf("reading fixtures: %v", err)
	}
	doc.BuildDirIndex()
	var pa testmark.PatchAccumulator
	for _, dirent := range doc.DirEnt.ChildrenList {
		t.Run(dirent.Name, func(t *testing.T) {
			cfgEnt := dirent.Children["config.yaml"]
			resEnt := dirent.Children["result"]
			if cfgEnt == nil || cfgEnt.Hunk == nil || resEnt == nil || resEnt.Hunk == nil {
				t.Fatalf("fixture %q needs both a config.yaml and a result hunk", dirent.Name)
			}
			// The config sits in a subdir of the scratch space, so a "../" relative
			// path in a fixture resolves inside scratch too ($PARENT in results).
			dir := filepath.Join(t.TempDir(), "etc")
			if err := os.MkdirAll(dir, 0o755); err != nil {
				t.Fatal(err)
			}
			cfgPath := filepath.Join(dir, "config.yaml")
			if err := os.WriteFile(cfgPath, cfgEnt.Hunk.Body, 0o644); err != nil {
				t.Fatal(err)
			}
			got := describeLoad(cfgPath, dir)
			if *testmark.Regen {
				pa.AppendPatchIfBodyDiffers(*resEnt.Hunk, []byte(got))
			} else if got != string(resEnt.Hunk.Body) {
				t.Errorf("result mismatch:\n--- got:\n%s--- want:\n%s", got, resEnt.Hunk.Body)
			}
		})
	}
	if *testmark.Regen {
		if err := pa.WriteFileWithPatches(doc, "testdata/config.md"); err != nil {
			t.Fatal(err)
		}
	}
}

// describeLoad renders a loadConfig outcome as the stable text the fixtures assert on.
// The scratch directory the config lives in is rewritten to "$BASE" (and its parent,
// reachable via "../" paths, to "$PARENT"), so the fixtures stay location-independent.
func describeLoad(cfgPath, base string) string {
	anonymize := func(s string) string {
		s = strings.ReplaceAll(s, base, "$BASE")
		return strings.ReplaceAll(s, filepath.Dir(base), "$PARENT")
	}
	cfg, err := loadConfig(cfgPath)
	if err != nil {
		return "error: " + anonymize(err.Error()) + "\n"
	}
	var sb strings.Builder
	for _, name := range sortedNames(cfg.Repos) {
		rc := cfg.Repos[name]
		fmt.Fprintf(&sb, "repo %s: path=%s", name, anonymize(rc.Path))
		if rc.Description != "" {
			fmt.Fprintf(&sb, " description=%q", rc.Description)
		}
		sb.WriteString("\n")
	}
	return sb.String()
}

config_test.go · 2.6 KiB · ef8eddc0ca