@@ -302,3 +302,109 @@ func TestFindFieldByTagWithMeta_NonStructValue(t *testing.T) {
302302 })
303303 }
304304}
305+
306+ func TestSetConfigValue_NonPrimitiveFields (t * testing.T ) {
307+ // Test that attempting to set non-primitive types returns descriptive errors
308+ tests := []struct {
309+ name string
310+ path string
311+ value string
312+ expectedError string
313+ }{
314+ {
315+ name : "slice field" ,
316+ path : "experimental" ,
317+ value : "value" ,
318+ expectedError : "unsupported type slice" ,
319+ },
320+ {
321+ name : "slice of structs" ,
322+ path : "storage" ,
323+ value : "value" ,
324+ expectedError : "unsupported type slice" ,
325+ },
326+ {
327+ name : "map field" ,
328+ path : "telemetry.headers" ,
329+ value : "value" ,
330+ expectedError : "unsupported type map" ,
331+ },
332+ }
333+
334+ for _ , tt := range tests {
335+ t .Run (tt .name , func (t * testing.T ) {
336+ data := & Data {}
337+ err := SetConfigValue (data , tt .path , tt .value )
338+ require .Error (t , err )
339+ assert .Contains (t , err .Error (), tt .expectedError )
340+ })
341+ }
342+ }
343+
344+ // Test types for named type validation
345+ type testNamedString string
346+ type testNamedInt int
347+ type testNamedBool bool
348+
349+ type testNamedStruct struct {
350+ StringField testNamedString `toml:"string-field" yaml:"string-field" json:"string-field"`
351+ IntField testNamedInt `toml:"int-field" yaml:"int-field" json:"int-field"`
352+ BoolField testNamedBool `toml:"bool-field" yaml:"bool-field" json:"bool-field"`
353+ }
354+
355+ func TestSetConfigValue_NamedTypes (t * testing.T ) {
356+ // Test that SetString/SetInt/SetBool work correctly with named types
357+ // This validates that reflection-based setters work on named types, not just primitives
358+ tests := []struct {
359+ name string
360+ path string
361+ value string
362+ validate func (* testing.T , * testNamedStruct )
363+ }{
364+ {
365+ name : "named string type" ,
366+ path : "string-field" ,
367+ value : "test-value" ,
368+ validate : func (t * testing.T , d * testNamedStruct ) {
369+ assert .Equal (t , testNamedString ("test-value" ), d .StringField )
370+ assert .IsType (t , testNamedString ("" ), d .StringField )
371+ },
372+ },
373+ {
374+ name : "named int type" ,
375+ path : "int-field" ,
376+ value : "42" ,
377+ validate : func (t * testing.T , d * testNamedStruct ) {
378+ assert .Equal (t , testNamedInt (42 ), d .IntField )
379+ assert .IsType (t , testNamedInt (0 ), d .IntField )
380+ },
381+ },
382+ {
383+ name : "named bool type" ,
384+ path : "bool-field" ,
385+ value : "true" ,
386+ validate : func (t * testing.T , d * testNamedStruct ) {
387+ assert .Equal (t , testNamedBool (true ), d .BoolField )
388+ assert .IsType (t , testNamedBool (false ), d .BoolField )
389+ },
390+ },
391+ }
392+
393+ for _ , tt := range tests {
394+ t .Run (tt .name , func (t * testing.T ) {
395+ data := & testNamedStruct {}
396+ err := setFieldByPath (reflect .ValueOf (data ).Elem (), []string {tt .path }, tt .value )
397+ require .NoError (t , err )
398+ tt .validate (t , data )
399+ })
400+ }
401+ }
402+
403+ func TestSetConfigValue_NamedTypes_RealConfig (t * testing.T ) {
404+ // Test named types in actual config (LogLevel)
405+ data := & Data {}
406+ err := SetConfigValue (data , "logs.level" , "debug" )
407+ require .NoError (t , err )
408+ assert .Equal (t , LogLevel ("debug" ), data .Logs .Level )
409+ assert .IsType (t , LogLevel ("" ), data .Logs .Level )
410+ }
0 commit comments