Skip to content

Commit d2818fc

Browse files
test(utilities): add tests for previously-uncovered helpers
internal/utilities/strings.go, context.go, and io.go held small pure-ish helpers but had no test coverage. Add focused unit tests so behaviour changes get caught: round-trip tests for StringValue and StringPtr; a context-key formatting check plus set/read/replace/derive cases for WithRequestID and GetRequestID; cancellation and completion cases for WaitForCleanup; and behaviour assertions for SafeClose covering the happy path, the error path, and io.NopCloser. Coverage for the package goes from 50.8% to 62.4% with no behaviour changes. Signed-off-by: Manas Srivastava <mastermanas805@gmail.com>
1 parent 7f88985 commit d2818fc

3 files changed

Lines changed: 170 additions & 0 deletions

File tree

internal/utilities/context_test.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package utilities
2+
3+
import (
4+
"context"
5+
"sync"
6+
"testing"
7+
"time"
8+
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
func TestContextKeyString(t *testing.T) {
13+
require.Equal(t, "gotrue api context key request_id", contextKey("request_id").String())
14+
require.Equal(t, "gotrue api context key ", contextKey("").String())
15+
}
16+
17+
func TestRequestIDRoundtrip(t *testing.T) {
18+
t.Run("set then read", func(t *testing.T) {
19+
ctx := WithRequestID(context.Background(), "abc-123")
20+
require.Equal(t, "abc-123", GetRequestID(ctx))
21+
})
22+
23+
t.Run("missing key returns empty string", func(t *testing.T) {
24+
require.Equal(t, "", GetRequestID(context.Background()))
25+
})
26+
27+
t.Run("set replaces previous value", func(t *testing.T) {
28+
ctx := WithRequestID(context.Background(), "first")
29+
ctx = WithRequestID(ctx, "second")
30+
require.Equal(t, "second", GetRequestID(ctx))
31+
})
32+
33+
t.Run("derived context inherits value", func(t *testing.T) {
34+
ctx := WithRequestID(context.Background(), "parent-id")
35+
child, cancel := context.WithCancel(ctx)
36+
defer cancel()
37+
require.Equal(t, "parent-id", GetRequestID(child))
38+
})
39+
}
40+
41+
func TestWaitForCleanup(t *testing.T) {
42+
t.Run("returns when wait group is done", func(t *testing.T) {
43+
var wg sync.WaitGroup
44+
wg.Add(1)
45+
go func() {
46+
time.Sleep(10 * time.Millisecond)
47+
wg.Done()
48+
}()
49+
50+
done := make(chan struct{})
51+
go func() {
52+
defer close(done)
53+
WaitForCleanup(context.Background(), &wg)
54+
}()
55+
56+
select {
57+
case <-done:
58+
case <-time.After(time.Second):
59+
t.Fatal("WaitForCleanup did not return after wg.Done()")
60+
}
61+
})
62+
63+
t.Run("returns when context is cancelled before wait group is done", func(t *testing.T) {
64+
var wg sync.WaitGroup
65+
wg.Add(1)
66+
67+
ctx, cancel := context.WithCancel(context.Background())
68+
done := make(chan struct{})
69+
go func() {
70+
defer close(done)
71+
WaitForCleanup(ctx, &wg)
72+
}()
73+
74+
cancel()
75+
76+
select {
77+
case <-done:
78+
case <-time.After(time.Second):
79+
t.Fatal("WaitForCleanup did not return after context cancellation")
80+
}
81+
82+
wg.Done()
83+
})
84+
}

internal/utilities/io_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package utilities
2+
3+
import (
4+
"errors"
5+
"io"
6+
"testing"
7+
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
type closerFunc func() error
12+
13+
func (f closerFunc) Close() error { return f() }
14+
15+
func TestSafeClose(t *testing.T) {
16+
t.Run("calls Close on the underlying closer", func(t *testing.T) {
17+
called := false
18+
c := closerFunc(func() error {
19+
called = true
20+
return nil
21+
})
22+
SafeClose(c)
23+
require.True(t, called, "Close should have been invoked")
24+
})
25+
26+
t.Run("does not panic when Close returns an error", func(t *testing.T) {
27+
c := closerFunc(func() error { return errors.New("close failed") })
28+
require.NotPanics(t, func() { SafeClose(c) })
29+
})
30+
31+
t.Run("does not panic for io.NopCloser", func(t *testing.T) {
32+
require.NotPanics(t, func() { SafeClose(io.NopCloser(nil)) })
33+
})
34+
}

internal/utilities/strings_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package utilities
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
)
8+
9+
func TestStringValue(t *testing.T) {
10+
t.Run("nil pointer returns empty string", func(t *testing.T) {
11+
require.Equal(t, "", StringValue(nil))
12+
})
13+
14+
t.Run("pointer to empty string returns empty string", func(t *testing.T) {
15+
empty := ""
16+
require.Equal(t, "", StringValue(&empty))
17+
})
18+
19+
t.Run("pointer to non-empty string returns the value", func(t *testing.T) {
20+
s := "hello"
21+
require.Equal(t, "hello", StringValue(&s))
22+
})
23+
}
24+
25+
func TestStringPtr(t *testing.T) {
26+
t.Run("empty string returns nil", func(t *testing.T) {
27+
require.Nil(t, StringPtr(""))
28+
})
29+
30+
t.Run("non-empty string returns a pointer to that value", func(t *testing.T) {
31+
p := StringPtr("hello")
32+
require.NotNil(t, p)
33+
require.Equal(t, "hello", *p)
34+
})
35+
36+
t.Run("returned pointer is independent of the input variable", func(t *testing.T) {
37+
s := "original"
38+
p := StringPtr(s)
39+
require.Equal(t, "original", *p)
40+
s = "mutated"
41+
require.Equal(t, "original", *p)
42+
})
43+
}
44+
45+
func TestStringValueAndStringPtrRoundtrip(t *testing.T) {
46+
cases := []string{"", "hello", "with spaces", "with\nnewline", "🦄"}
47+
for _, c := range cases {
48+
t.Run(c, func(t *testing.T) {
49+
require.Equal(t, c, StringValue(StringPtr(c)))
50+
})
51+
}
52+
}

0 commit comments

Comments
 (0)