internal/encoder/encoder_test.go

package encoder_test

import (
	"bytes"
	"sort"
	"testing"

	"github.com/google/go-cmp/cmp"
	"mercemay.top/src/lambdalog/internal/encoder"
)

func TestRegistry_RegisterAndLookup(t *testing.T) {
	reg := &encoder.Registry{}
	t.Cleanup(func() { /* no shared state */ })

	reg.Register(encoder.NopEncoder{})
	got, err := reg.Lookup("nop")
	if err != nil {
		t.Fatalf("lookup: %v", err)
	}
	if got.Name() != "nop" {
		t.Fatalf("name = %q, want nop", got.Name())
	}
}

func TestRegistry_DuplicateRegisterPanics(t *testing.T) {
	t.Helper()
	reg := &encoder.Registry{}
	reg.Register(encoder.NopEncoder{})
	defer func() {
		if recover() == nil {
			t.Fatal("expected panic on duplicate registration")
		}
	}()
	reg.Register(encoder.NopEncoder{})
}

func TestRegistry_LookupMissing(t *testing.T) {
	reg := &encoder.Registry{}
	if _, err := reg.Lookup("absent"); err == nil {
		t.Fatal("expected error for missing encoder")
	}
}

func TestRegistry_Names(t *testing.T) {
	reg := &encoder.Registry{}
	reg.Register(encoder.NopEncoder{})
	names := reg.Names()
	sort.Strings(names)
	if diff := cmp.Diff([]string{"nop"}, names); diff != "" {
		t.Fatalf("names (-want +got):\n%s", diff)
	}
}

func TestNopEncoder_Encode(t *testing.T) {
	cases := []struct {
		name string
		rec  encoder.Record
	}{
		{name: "empty", rec: encoder.Record{}},
		{name: "with-fields", rec: encoder.Record{
			Message: "hello",
			Fields:  []encoder.Field{{Key: "k", Value: 1}},
		}},
	}
	for _, tc := range cases {
		tc := tc
		t.Run(tc.name, func(t *testing.T) {
			t.Helper()
			var buf bytes.Buffer
			if err := (encoder.NopEncoder{}).Encode(&buf, tc.rec); err != nil {
				t.Fatalf("encode: %v", err)
			}
			if buf.Len() != 0 {
				t.Fatalf("nop wrote %d bytes", buf.Len())
			}
		})
	}
}

func TestNew_UsesDefaultRegistry(t *testing.T) {
	got, err := encoder.New("nop")
	if err != nil {
		t.Fatalf("New: %v", err)
	}
	if got == nil {
		t.Fatal("New returned nil encoder")
	}
}