Skip to content

Commit 2b18639

Browse files
committed
replace nil with stubs
1 parent 1ae4a03 commit 2b18639

File tree

8 files changed

+49
-31
lines changed

8 files changed

+49
-31
lines changed

pkg/github/context_tools_test.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,10 @@ func Test_GetMe(t *testing.T) {
9696
t.Run(tc.name, func(t *testing.T) {
9797
var deps ToolDependencies
9898
if tc.clientErr != "" {
99-
deps = stubDeps{clientFn: stubClientFnErr(tc.clientErr)}
99+
deps = stubDeps{clientFn: stubClientFnErr(tc.clientErr), obsv: stubExporters()}
100100
} else {
101-
deps = BaseDeps{Client: github.NewClient(tc.mockedClient)}
101+
obs := stubExporters()
102+
deps = BaseDeps{Client: github.NewClient(tc.mockedClient), Obsv: obs}
102103
}
103104
handler := serverTool.Handler(deps)
104105

@@ -304,7 +305,7 @@ func Test_GetTeams(t *testing.T) {
304305
{
305306
name: "getting client fails",
306307
makeDeps: func() ToolDependencies {
307-
return stubDeps{clientFn: stubClientFnErr("expected test error")}
308+
return stubDeps{clientFn: stubClientFnErr("expected test error"), obsv: stubExporters()}
308309
},
309310
requestArgs: map[string]any{},
310311
expectToolError: true,
@@ -315,6 +316,7 @@ func Test_GetTeams(t *testing.T) {
315316
makeDeps: func() ToolDependencies {
316317
return BaseDeps{
317318
Client: github.NewClient(httpClientUserFails()),
319+
Obsv: stubExporters(),
318320
}
319321
},
320322
requestArgs: map[string]any{},
@@ -327,6 +329,7 @@ func Test_GetTeams(t *testing.T) {
327329
return stubDeps{
328330
clientFn: stubClientFnFromHTTP(httpClientWithUser()),
329331
gqlClientFn: stubGQLClientFnErr("GraphQL client error"),
332+
obsv: stubExporters(),
330333
}
331334
},
332335
requestArgs: map[string]any{},
@@ -469,7 +472,7 @@ func Test_GetTeamMembers(t *testing.T) {
469472
},
470473
{
471474
name: "getting GraphQL client fails",
472-
deps: stubDeps{gqlClientFn: stubGQLClientFnErr("GraphQL client error")},
475+
deps: stubDeps{gqlClientFn: stubGQLClientFnErr("GraphQL client error"), obsv: stubExporters()},
473476
requestArgs: map[string]any{
474477
"org": "testorg",
475478
"team_slug": "testteam",

pkg/github/dependencies.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -188,17 +188,11 @@ func (d BaseDeps) GetContentWindowSize() int { return d.ContentWindowSize }
188188

189189
// Logger implements ToolDependencies.
190190
func (d BaseDeps) Logger(_ context.Context) *slog.Logger {
191-
if d.Obsv == nil {
192-
return slog.New(slog.DiscardHandler)
193-
}
194191
return d.Obsv.Logger()
195192
}
196193

197194
// Metrics implements ToolDependencies.
198195
func (d BaseDeps) Metrics(ctx context.Context) metrics.Metrics {
199-
if d.Obsv == nil {
200-
return metrics.NewNoopMetrics()
201-
}
202196
return d.Obsv.Metrics(ctx)
203197
}
204198

pkg/github/dependencies_test.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,21 @@ package github_test
33
import (
44
"context"
55
"errors"
6+
"log/slog"
67
"testing"
78

89
"github.com/github/github-mcp-server/pkg/github"
10+
"github.com/github/github-mcp-server/pkg/observability"
11+
"github.com/github/github-mcp-server/pkg/observability/metrics"
912
"github.com/github/github-mcp-server/pkg/translations"
1013
"github.com/stretchr/testify/assert"
1114
)
1215

16+
func testExporters() observability.Exporters {
17+
obs, _ := observability.NewExporters(slog.New(slog.DiscardHandler), metrics.NewNoopMetrics())
18+
return obs
19+
}
20+
1321
func TestIsFeatureEnabled_WithEnabledFlag(t *testing.T) {
1422
t.Parallel()
1523

@@ -28,7 +36,7 @@ func TestIsFeatureEnabled_WithEnabledFlag(t *testing.T) {
2836
github.FeatureFlags{},
2937
0, // contentWindowSize
3038
checker, // featureChecker
31-
nil, // obsv
39+
testExporters(),
3240
)
3341

3442
// Test enabled flag
@@ -53,7 +61,7 @@ func TestIsFeatureEnabled_WithoutChecker(t *testing.T) {
5361
github.FeatureFlags{},
5462
0, // contentWindowSize
5563
nil, // featureChecker (nil)
56-
nil, // obsv
64+
testExporters(),
5765
)
5866

5967
// Should return false when checker is nil
@@ -78,7 +86,7 @@ func TestIsFeatureEnabled_EmptyFlagName(t *testing.T) {
7886
github.FeatureFlags{},
7987
0, // contentWindowSize
8088
checker, // featureChecker
81-
nil, // obsv
89+
testExporters(),
8290
)
8391

8492
// Should return false for empty flag name
@@ -103,7 +111,7 @@ func TestIsFeatureEnabled_CheckerError(t *testing.T) {
103111
github.FeatureFlags{},
104112
0, // contentWindowSize
105113
checker, // featureChecker
106-
nil, // obsv
114+
testExporters(),
107115
)
108116

109117
// Should return false and log error (not crash)

pkg/github/dynamic_tools_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ func TestDynamicTools_EnableToolset(t *testing.T) {
136136
deps := DynamicToolDependencies{
137137
Server: server,
138138
Inventory: reg,
139-
ToolDeps: NewBaseDeps(nil, nil, nil, nil, translations.NullTranslationHelper, FeatureFlags{}, 0, nil, nil),
139+
ToolDeps: NewBaseDeps(nil, nil, nil, nil, translations.NullTranslationHelper, FeatureFlags{}, 0, nil, stubExporters()),
140140
T: translations.NullTranslationHelper,
141141
}
142142

pkg/github/feature_flags_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ func TestHelloWorld_ConditionalBehavior_Featureflag(t *testing.T) {
104104
FeatureFlags{},
105105
0,
106106
checker,
107-
nil,
107+
stubExporters(),
108108
)
109109

110110
// Get the tool and its handler
@@ -167,7 +167,7 @@ func TestHelloWorld_ConditionalBehavior_Config(t *testing.T) {
167167
FeatureFlags{InsidersMode: tt.insidersMode},
168168
0,
169169
nil,
170-
nil,
170+
stubExporters(),
171171
)
172172

173173
// Get the tool and its handler

pkg/github/server_test.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,20 @@ func (s stubDeps) GetFlags(_ context.Context) FeatureFlags { return s.
6565
func (s stubDeps) GetContentWindowSize() int { return s.contentWindowSize }
6666
func (s stubDeps) IsFeatureEnabled(_ context.Context, _ string) bool { return false }
6767
func (s stubDeps) Logger(_ context.Context) *slog.Logger {
68-
if s.obsv != nil {
69-
return s.obsv.Logger()
70-
}
71-
return slog.New(slog.DiscardHandler)
68+
return s.obsv.Logger()
7269
}
7370
func (s stubDeps) Metrics(ctx context.Context) metrics.Metrics {
74-
if s.obsv != nil {
75-
return s.obsv.Metrics(ctx)
76-
}
77-
return metrics.NewNoopMetrics()
71+
return s.obsv.Metrics(ctx)
7872
}
7973

8074
// Helper functions to create stub client functions for error testing
75+
76+
// stubExporters returns a discard-logger + noop-metrics Exporters for tests.
77+
func stubExporters() observability.Exporters {
78+
obs, _ := observability.NewExporters(slog.New(slog.DiscardHandler), metrics.NewNoopMetrics())
79+
return obs
80+
}
81+
8182
func stubClientFnFromHTTP(httpClient *http.Client) func(context.Context) (*gogithub.Client, error) {
8283
return func(_ context.Context) (*gogithub.Client, error) {
8384
return gogithub.NewClient(httpClient), nil
@@ -141,7 +142,7 @@ func TestNewMCPServer_CreatesSuccessfully(t *testing.T) {
141142
InsidersMode: false,
142143
}
143144

144-
deps := stubDeps{}
145+
deps := stubDeps{obsv: stubExporters()}
145146

146147
// Build inventory
147148
inv, err := NewInventory(cfg.Translator).

pkg/observability/observability.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,18 @@ type exporters struct {
2222

2323
// NewExporters creates an Exporters bundle. Pass a configured *slog.Logger
2424
// (with whatever slog.Handler you need) and a Metrics implementation.
25-
// The logger must not be nil; use slog.New(slog.DiscardHandler) if logging is unwanted.
26-
func NewExporters(logger *slog.Logger, metrics metrics.Metrics) (Exporters, error) {
25+
// Neither may be nil; use slog.New(slog.DiscardHandler) and metrics.NewNoopMetrics()
26+
// if logging or metrics are unwanted.
27+
func NewExporters(logger *slog.Logger, m metrics.Metrics) (Exporters, error) {
2728
if logger == nil {
2829
return nil, errors.New("logger must not be nil: use slog.New(slog.DiscardHandler) to discard logs")
2930
}
31+
if m == nil {
32+
return nil, errors.New("metrics must not be nil: use metrics.NewNoopMetrics() to discard metrics")
33+
}
3034
return &exporters{
3135
logger: logger,
32-
metrics: metrics,
36+
metrics: m,
3337
}, nil
3438
}
3539

pkg/observability/observability_test.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,24 @@ func TestNewExporters(t *testing.T) {
2323
}
2424

2525
func TestNewExporters_WithNilLogger(t *testing.T) {
26-
_, err := NewExporters(nil, nil)
26+
_, err := NewExporters(nil, metrics.NewNoopMetrics())
2727
require.Error(t, err)
2828
assert.Contains(t, err.Error(), "logger must not be nil")
2929
}
3030

31+
func TestNewExporters_WithNilMetrics(t *testing.T) {
32+
_, err := NewExporters(slog.New(slog.DiscardHandler), nil)
33+
require.Error(t, err)
34+
assert.Contains(t, err.Error(), "metrics must not be nil")
35+
}
36+
3137
func TestNewExporters_WithDiscardLogger(t *testing.T) {
3238
logger := slog.New(slog.DiscardHandler)
33-
exp, err := NewExporters(logger, nil)
39+
m := metrics.NewNoopMetrics()
40+
exp, err := NewExporters(logger, m)
3441

3542
require.NoError(t, err)
3643
assert.NotNil(t, exp)
3744
assert.Equal(t, logger, exp.Logger())
45+
assert.Equal(t, m, exp.Metrics(context.Background()))
3846
}

0 commit comments

Comments
 (0)