fields_test.go

package lambdalog

import (
	"errors"
	"testing"
)

func TestString_Int_Bool_Err_Constructors(t *testing.T) {
	t.Parallel()

	cases := []struct {
		name string
		got  Attr
		want Attr
	}{
		{"string", String("k", "v"), Attr{Key: "k", Value: "v"}},
		{"int", Int("n", 7), Attr{Key: "n", Value: 7}},
		{"int64", Int64("n", 42), Attr{Key: "n", Value: int64(42)}},
		{"bool", Bool("ok", true), Attr{Key: "ok", Value: true}},
		{"err", Err(errors.New("boom")), Attr{Key: "err", Value: "boom"}},
		{"err-nil", Err(nil), Attr{Key: "err", Value: nil}},
	}

	for _, tc := range cases {
		tc := tc
		t.Run(tc.name, func(t *testing.T) {
			t.Parallel()
			if tc.got != tc.want {
				t.Fatalf("got %+v, want %+v", tc.got, tc.want)
			}
		})
	}
}

func TestGroup_FlattensIntoMap(t *testing.T) {
	t.Parallel()

	a := Group("http",
		String("method", "GET"),
		Int("status", 200),
	)
	m, ok := a.Value.(map[string]any)
	if !ok {
		t.Fatalf("Group value should be map[string]any, got %T", a.Value)
	}
	if m["method"] != "GET" || m["status"] != 200 {
		t.Fatalf("unexpected group contents: %+v", m)
	}
}

func TestMerge_RightWinsOnCollision(t *testing.T) {
	t.Parallel()

	left := []Attr{String("region", "us-east-1"), String("svc", "auth")}
	right := []Attr{String("region", "eu-west-1"), Int("attempt", 3)}

	got := Merge(left, right)
	if len(got) != 3 {
		t.Fatalf("expected 3 attrs, got %d", len(got))
	}
	for _, a := range got {
		if a.Key == "region" && a.Value != "eu-west-1" {
			t.Fatalf("right should win: %+v", a)
		}
	}

	// Mutating the result must not affect the inputs.
	got[0] = String("region", "mutated")
	if left[0].Value != "us-east-1" {
		t.Fatal("Merge should not alias its inputs")
	}
}

func TestCopy_DeepCopiesGroups(t *testing.T) {
	t.Parallel()

	src := []Attr{Group("http", String("method", "GET"))}
	dst := Copy(src)
	// mutate the copy's inner map and ensure the source is unchanged
	m := dst[0].Value.(map[string]any)
	m["method"] = "POST"
	if src[0].Value.(map[string]any)["method"] != "GET" {
		t.Fatal("Copy should have deep-copied nested groups")
	}
}

func TestLogger_WithAttrsMergesCorrectly(t *testing.T) {
	t.Parallel()
	t.Helper()

	base := New(nil).With("service", "checkout")
	child := base.WithAttrs(String("region", "us-east-1"), Int("attempt", 1))

	if len(child.attrs) != 3 {
		t.Fatalf("expected 3 attrs on child, got %d", len(child.attrs))
	}
	if len(base.attrs) != 1 {
		t.Fatal("WithAttrs must not mutate parent")
	}
}

func TestAsPairs_RoundTrip(t *testing.T) {
	t.Parallel()

	attrs := []Attr{String("a", "1"), Int("b", 2)}
	pairs := asPairs(attrs)
	if len(pairs) != 4 {
		t.Fatalf("expected 4 elements, got %d", len(pairs))
	}
	if pairs[0] != "a" || pairs[1] != "1" || pairs[2] != "b" || pairs[3] != 2 {
		t.Fatalf("pair order wrong: %v", pairs)
	}
}