1package event
2
3// These tests verify that the Error function correctly handles various
4// scenarios. These tests will not log anything.
5
6import (
7 "reflect"
8 "testing"
9
10 "github.com/posthog/posthog-go"
11)
12
13func TestError(t *testing.T) {
14 t.Run("returns early when client is nil", func(t *testing.T) {
15 // This test verifies that when the PostHog client is not initialized
16 // the Error function safely returns early without attempting to
17 // enqueue any events. This is important during initialization or when
18 // metrics are disabled, as we don't want the error reporting mechanism
19 // itself to cause panics.
20 originalClient := client
21 defer func() {
22 client = originalClient
23 }()
24
25 client = nil
26 Error("test error", "key", "value")
27 })
28
29 t.Run("handles nil client without panicking", func(t *testing.T) {
30 // This test covers various edge cases where the error value might be
31 // nil, a string, or an error type.
32 originalClient := client
33 defer func() {
34 client = originalClient
35 }()
36
37 client = nil
38 Error(nil)
39 Error("some error")
40 Error(newDefaultTestError("runtime error"), "key", "value")
41 })
42
43 t.Run("handles error with properties", func(t *testing.T) {
44 // This test verifies that the Error function can handle additional
45 // key-value properties that provide context about the error. These
46 // properties are typically passed when recovering from panics (i.e.,
47 // panic name, function name).
48 //
49 // Even with these additional properties, the function should handle
50 // them gracefully without panicking.
51 originalClient := client
52 defer func() {
53 client = originalClient
54 }()
55
56 client = nil
57 Error(
58 "test error",
59 "type", "test",
60 "severity", "high",
61 "source", "unit-test",
62 )
63 })
64}
65
66func TestPairsToProps(t *testing.T) {
67 t.Run("sets valid key value pairs", func(t *testing.T) {
68 got := pairsToProps("foo", "bar", "count", 3)
69 want := posthog.NewProperties().
70 Set("foo", "bar").
71 Set("count", 3)
72 if !reflect.DeepEqual(got, want) {
73 t.Fatalf("pairsToProps() = %#v, want %#v", got, want)
74 }
75 })
76
77 t.Run("returns empty properties for odd pairs", func(t *testing.T) {
78 got := pairsToProps("foo", "bar", "count")
79 if len(got) != 0 {
80 t.Fatalf("pairsToProps() should return empty properties, got %#v", got)
81 }
82 })
83
84 t.Run("ignores non-string key and continues", func(t *testing.T) {
85 got := pairsToProps(123, "bad", "ok", true)
86 want := posthog.NewProperties().Set("ok", true)
87 if !reflect.DeepEqual(got, want) {
88 t.Fatalf("pairsToProps() = %#v, want %#v", got, want)
89 }
90 })
91}
92
93// newDefaultTestError creates a test error that mimics runtime panic
94// errors. This helps us testing that the Error function can handle various
95// error types, including those that might be passed from a panic recovery
96// scenario.
97func newDefaultTestError(s string) error {
98 return testError(s)
99}
100
101type testError string
102
103func (e testError) Error() string {
104 return string(e)
105}