Skip to content

Commit 00a3081

Browse files
author
Virgil
committed
fix(forge): make client accessors nil-safe
Co-Authored-By: Virgil <virgil@lethean.io>
1 parent d08c875 commit 00a3081

File tree

4 files changed

+92
-6
lines changed

4 files changed

+92
-6
lines changed

client.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ type Client struct {
171171
//
172172
// baseURL := client.BaseURL()
173173
func (c *Client) BaseURL() string {
174+
if c == nil {
175+
return ""
176+
}
174177
return c.baseURL
175178
}
176179

@@ -180,6 +183,9 @@ func (c *Client) BaseURL() string {
180183
//
181184
// rl := client.RateLimit()
182185
func (c *Client) RateLimit() RateLimit {
186+
if c == nil {
187+
return RateLimit{}
188+
}
183189
return c.rateLimit
184190
}
185191

@@ -189,6 +195,9 @@ func (c *Client) RateLimit() RateLimit {
189195
//
190196
// ua := client.UserAgent()
191197
func (c *Client) UserAgent() string {
198+
if c == nil {
199+
return ""
200+
}
192201
return c.userAgent
193202
}
194203

@@ -198,6 +207,9 @@ func (c *Client) UserAgent() string {
198207
//
199208
// hc := client.HTTPClient()
200209
func (c *Client) HTTPClient() *http.Client {
210+
if c == nil {
211+
return nil
212+
}
201213
return c.httpClient
202214
}
203215

@@ -232,6 +244,9 @@ func (c *Client) GoString() string { return c.String() }
232244
// _ = "authenticated"
233245
// }
234246
func (c *Client) HasToken() bool {
247+
if c == nil {
248+
return false
249+
}
235250
return c.token != ""
236251
}
237252

client_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,25 @@ func TestClient_HasToken_Bad(t *testing.T) {
215215
}
216216
}
217217

218+
func TestClient_NilSafeAccessors(t *testing.T) {
219+
var c *Client
220+
if got := c.BaseURL(); got != "" {
221+
t.Fatalf("got BaseURL()=%q, want empty string", got)
222+
}
223+
if got := c.RateLimit(); got != (RateLimit{}) {
224+
t.Fatalf("got RateLimit()=%#v, want zero value", got)
225+
}
226+
if got := c.UserAgent(); got != "" {
227+
t.Fatalf("got UserAgent()=%q, want empty string", got)
228+
}
229+
if got := c.HTTPClient(); got != nil {
230+
t.Fatal("expected HTTPClient() to return nil")
231+
}
232+
if got := c.HasToken(); got {
233+
t.Fatal("expected HasToken() to report false")
234+
}
235+
}
236+
218237
func TestClient_WithHTTPClient_Good(t *testing.T) {
219238
custom := &http.Client{}
220239
c := NewClient("https://forge.lthn.ai", "tok", WithHTTPClient(custom))

forge.go

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,35 +72,60 @@ func NewForge(url, token string, opts ...Option) *Forge {
7272
// Usage:
7373
//
7474
// client := f.Client()
75-
func (f *Forge) Client() *Client { return f.client }
75+
func (f *Forge) Client() *Client {
76+
if f == nil {
77+
return nil
78+
}
79+
return f.client
80+
}
7681

7782
// BaseURL returns the configured Forgejo base URL.
7883
//
7984
// Usage:
8085
//
8186
// baseURL := f.BaseURL()
82-
func (f *Forge) BaseURL() string { return f.client.BaseURL() }
87+
func (f *Forge) BaseURL() string {
88+
if f == nil || f.client == nil {
89+
return ""
90+
}
91+
return f.client.BaseURL()
92+
}
8393

8494
// RateLimit returns the last known rate limit information.
8595
//
8696
// Usage:
8797
//
8898
// rl := f.RateLimit()
89-
func (f *Forge) RateLimit() RateLimit { return f.client.RateLimit() }
99+
func (f *Forge) RateLimit() RateLimit {
100+
if f == nil || f.client == nil {
101+
return RateLimit{}
102+
}
103+
return f.client.RateLimit()
104+
}
90105

91106
// UserAgent returns the configured User-Agent header value.
92107
//
93108
// Usage:
94109
//
95110
// ua := f.UserAgent()
96-
func (f *Forge) UserAgent() string { return f.client.UserAgent() }
111+
func (f *Forge) UserAgent() string {
112+
if f == nil || f.client == nil {
113+
return ""
114+
}
115+
return f.client.UserAgent()
116+
}
97117

98118
// HTTPClient returns the configured underlying HTTP client.
99119
//
100120
// Usage:
101121
//
102122
// hc := f.HTTPClient()
103-
func (f *Forge) HTTPClient() *http.Client { return f.client.HTTPClient() }
123+
func (f *Forge) HTTPClient() *http.Client {
124+
if f == nil || f.client == nil {
125+
return nil
126+
}
127+
return f.client.HTTPClient()
128+
}
104129

105130
// HasToken reports whether the Forge client was configured with an API token.
106131
//
@@ -109,7 +134,12 @@ func (f *Forge) HTTPClient() *http.Client { return f.client.HTTPClient() }
109134
// if f.HasToken() {
110135
// _ = "authenticated"
111136
// }
112-
func (f *Forge) HasToken() bool { return f.client.HasToken() }
137+
func (f *Forge) HasToken() bool {
138+
if f == nil || f.client == nil {
139+
return false
140+
}
141+
return f.client.HasToken()
142+
}
113143

114144
// String returns a safe summary of the Forge client.
115145
//

forge_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,28 @@ func TestForge_HasToken_Bad(t *testing.T) {
8282
}
8383
}
8484

85+
func TestForge_NilSafeAccessors(t *testing.T) {
86+
var f *Forge
87+
if got := f.Client(); got != nil {
88+
t.Fatal("expected Client() to return nil")
89+
}
90+
if got := f.BaseURL(); got != "" {
91+
t.Fatalf("got BaseURL()=%q, want empty string", got)
92+
}
93+
if got := f.RateLimit(); got != (RateLimit{}) {
94+
t.Fatalf("got RateLimit()=%#v, want zero value", got)
95+
}
96+
if got := f.UserAgent(); got != "" {
97+
t.Fatalf("got UserAgent()=%q, want empty string", got)
98+
}
99+
if got := f.HTTPClient(); got != nil {
100+
t.Fatal("expected HTTPClient() to return nil")
101+
}
102+
if got := f.HasToken(); got {
103+
t.Fatal("expected HasToken() to report false")
104+
}
105+
}
106+
85107
func TestForge_String_Good(t *testing.T) {
86108
f := NewForge("https://forge.lthn.ai", "tok", WithUserAgent("go-forge/1.0"))
87109
got := fmt.Sprint(f)

0 commit comments

Comments
 (0)