output/file_test.go

package output_test

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

	"mercemay.top/src/lambdalog/output"
)

func TestFile_WritesAndCloses(t *testing.T) {
	dir := t.TempDir()
	path := filepath.Join(dir, "log.txt")
	w, err := output.File(output.FileOptions{Path: path})
	if err != nil {
		t.Fatalf("open: %v", err)
	}
	t.Cleanup(func() { _ = w.Close() })

	if _, err := io.WriteString(w, "hello\n"); err != nil {
		t.Fatalf("write: %v", err)
	}
	if err := w.Close(); err != nil {
		t.Fatalf("close: %v", err)
	}
	if _, err := io.WriteString(w, "after"); err == nil {
		t.Fatal("write after close should fail")
	}

	data, err := os.ReadFile(path)
	if err != nil {
		t.Fatalf("readfile: %v", err)
	}
	if !strings.Contains(string(data), "hello") {
		t.Fatalf("got %q", data)
	}
}

func TestFile_Rotates(t *testing.T) {
	dir := t.TempDir()
	path := filepath.Join(dir, "log.txt")
	w, err := output.File(output.FileOptions{Path: path, MaxBytes: 8, MaxBackups: 2})
	if err != nil {
		t.Fatalf("open: %v", err)
	}
	t.Cleanup(func() { _ = w.Close() })

	for i := 0; i < 5; i++ {
		io.WriteString(w, "xxxx") // 4 bytes each
	}
	_, errStat := os.Stat(path + ".1")
	if errStat != nil {
		t.Fatalf("rotated file missing: %v", errStat)
	}
}

func TestFile_CreatesDir(t *testing.T) {
	dir := t.TempDir()
	path := filepath.Join(dir, "sub", "log.txt")
	w, err := output.File(output.FileOptions{Path: path})
	if err != nil {
		t.Fatalf("open: %v", err)
	}
	t.Cleanup(func() { _ = w.Close() })
	if _, err := os.Stat(filepath.Dir(path)); err != nil {
		t.Fatalf("dir not created: %v", err)
	}
}

func TestFile_DefaultPath(t *testing.T) {
	t.Helper()
	// This runs in the test binary's cwd; clean up afterwards.
	w, err := output.File(output.FileOptions{})
	if err != nil {
		t.Fatalf("open: %v", err)
	}
	_ = w.Close()
	t.Cleanup(func() { _ = os.Remove("./lambdalog.log") })
}