package main

import (
	"reflect"
	"testing"
)

func TestRecovery(t *testing.T) {
	cases := []struct {
		kind string
		want []string
	}{
		{"direct", []string{"direct: boom"}},
		{"named", []string{"named: boom"}},
		{"helper", []string{"helper: <nil>", "outer: boom"}},
		{"builtin", []string{"outer: boom"}},
	}
	for _, tc := range cases {
		if got := recovery(tc.kind); !reflect.DeepEqual(got, tc.want) {
			t.Fatalf("%s: %v", tc.kind, got)
		}
	}
}
func TestIndirectSnippet(t *testing.T) {
	if got := indirect(); !reflect.DeepEqual(got, []string{"helper: <nil>", "outer: boom"}) {
		t.Fatal(got)
	}
}
func TestNilFunctionPanicTiming(t *testing.T) {
	registered := false
	defer func() {
		if recover() == nil || !registered {
			t.Fatal("nil deferred call must panic at execution")
		}
	}()
	var f func()
	defer f()
	registered = true
}
func TestLoopsAndClosures(t *testing.T) {
	a, b := loopValues()
	if !reflect.DeepEqual(a, []int{0, 1, 2}) || !reflect.DeepEqual(b, []int{3, 3, 3}) {
		t.Fatal(a, b)
	}
	c, d := counter(0), counter(0)
	if c() != 1 || c() != 2 || d() != 1 {
		t.Fatal("independent counters")
	}
}
func TestVariadicSharing(t *testing.T) {
	if total() != 0 {
		t.Fatal("zero arguments")
	}
	xs := []int{1, 2}
	replaceFirst(xs...)
	if xs[0] != 99 {
		t.Fatal(xs)
	}
}
