internal/pipeline/stage/load_test.go

package stage

import (
	"context"
	"os"
	"path/filepath"
	"testing"

	"mercemay.top/src/tilstream/internal/pipeline"
)

func writeFixture(t *testing.T, dir string, files map[string]string) {
	t.Helper()
	for name, body := range files {
		full := filepath.Join(dir, name)
		if err := os.MkdirAll(filepath.Dir(full), 0o755); err != nil {
			t.Fatal(err)
		}
		if err := os.WriteFile(full, []byte(body), 0o644); err != nil {
			t.Fatal(err)
		}
	}
}

func TestLoadReadsMarkdown(t *testing.T) {
	t.Parallel()
	cases := []struct {
		name    string
		files   map[string]string
		wantCnt int
	}{
		{"single", map[string]string{"a.md": "hi"}, 1},
		{"mixed", map[string]string{"a.md": "hi", "b.txt": "skip", "sub/c.md": "deep"}, 2},
		{"hidden_skipped", map[string]string{"_skip.md": "no", "ok.md": "yes"}, 1},
	}
	for _, tc := range cases {
		tc := tc
		t.Run(tc.name, func(t *testing.T) {
			t.Parallel()
			dir := t.TempDir()
			writeFixture(t, dir, tc.files)
			st := &pipeline.State{SourceDir: dir}
			if err := NewLoad().Run(context.Background(), st); err != nil {
				t.Fatalf("Run: %v", err)
			}
			if got := CountPosts(st); got != tc.wantCnt {
				t.Errorf("got %d posts, want %d", got, tc.wantCnt)
			}
		})
	}
}

func TestLoadRejectsOversizedFile(t *testing.T) {
	t.Parallel()
	dir := t.TempDir()
	big := make([]byte, 2048)
	writeFixture(t, dir, map[string]string{"big.md": string(big)})
	ld := NewLoad()
	ld.MaxBytes = 1024
	st := &pipeline.State{SourceDir: dir}
	if err := ld.Run(context.Background(), st); err == nil {
		t.Error("expected oversized error")
	}
}

func TestLoadEmptySourceDir(t *testing.T) {
	t.Parallel()
	t.Helper()
	st := &pipeline.State{}
	if err := NewLoad().Run(context.Background(), st); err == nil {
		t.Error("expected error for empty SourceDir")
	}
}