4
4
package configoptional
5
5
6
6
import (
7
+ "fmt"
7
8
"testing"
8
9
9
10
"github.com/stretchr/testify/assert"
@@ -339,10 +340,11 @@ func confFromYAML(t *testing.T, yaml string) *confmap.Conf {
339
340
return conf
340
341
}
341
342
342
- func TestComparePointer (t * testing.T ) {
343
+ func TestComparePointerUnmarshal (t * testing.T ) {
343
344
tests := []struct {
344
345
yaml string
345
346
}{
347
+ {yaml : "" },
346
348
{yaml : "sub: " },
347
349
{yaml : "sub: null" },
348
350
{yaml : "sub: {}" },
@@ -365,3 +367,96 @@ func TestComparePointer(t *testing.T) {
365
367
})
366
368
}
367
369
}
370
+
371
+ func TestOptionalMarshal (t * testing.T ) {
372
+ tests := []struct {
373
+ name string
374
+ value Config [Sub ]
375
+ expected map [string ]any
376
+ }{
377
+ {
378
+ name : "none (zero value)" ,
379
+ value : Config [Sub ]{},
380
+ expected : map [string ]any {"sub" : nil },
381
+ },
382
+ {
383
+ name : "none" ,
384
+ value : Config [Sub ]{Sub1 : None [Sub ]()},
385
+ expected : map [string ]any {"sub" : nil },
386
+ },
387
+ {
388
+ name : "default" ,
389
+ value : Config [Sub ]{Sub1 : Default (subDefault )},
390
+ expected : map [string ]any {"sub" : nil },
391
+ },
392
+ {
393
+ name : "some" ,
394
+ value : Config [Sub ]{Sub1 : Some (Sub {
395
+ Foo : "bar" ,
396
+ })},
397
+ expected : map [string ]any {
398
+ "sub" : map [string ]any {
399
+ "foo" : "bar" ,
400
+ },
401
+ },
402
+ },
403
+ }
404
+
405
+ for _ , test := range tests {
406
+ t .Run (test .name , func (t * testing.T ) {
407
+ conf := confmap .New ()
408
+ require .NoError (t , conf .Marshal (test .value ))
409
+ assert .Equal (t , test .expected , conf .ToStringMap ())
410
+ })
411
+ }
412
+ }
413
+
414
+ func TestComparePointerMarshal (t * testing.T ) {
415
+ type Wrap [T any ] struct {
416
+ // Note: passes without requiring "squash".
417
+ Sub1 T `mapstructure:"sub"`
418
+ }
419
+
420
+ type WrapOmitEmpty [T any ] struct {
421
+ // Note: passes without requiring "squash", except with Default-flavored Optional values.
422
+ Sub1 T `mapstructure:"sub,omitempty"`
423
+ }
424
+
425
+ tests := []struct {
426
+ pointer * Sub
427
+ optional Optional [Sub ]
428
+ skipOmitEmpty bool
429
+ }{
430
+ {pointer : nil , optional : None [Sub ]()},
431
+ {pointer : nil , optional : Default (subDefault ), skipOmitEmpty : true }, // does not work with omitempty
432
+ {pointer : & Sub {Foo : "bar" }, optional : Some (Sub {Foo : "bar" })},
433
+ }
434
+ for _ , test := range tests {
435
+ t .Run (fmt .Sprintf ("%v vs %v" , test .pointer , test .optional ), func (t * testing.T ) {
436
+ wrapPointer := Wrap [* Sub ]{Sub1 : test .pointer }
437
+ confPointer := confmap .NewFromStringMap (nil )
438
+ require .NoError (t , confPointer .Marshal (wrapPointer ))
439
+
440
+ wrapOptional := Wrap [Optional [Sub ]]{Sub1 : test .optional }
441
+ confOptional := confmap .NewFromStringMap (nil )
442
+ require .NoError (t , confOptional .Marshal (wrapOptional ))
443
+
444
+ assert .Equal (t , confPointer .ToStringMap (), confOptional .ToStringMap ())
445
+ })
446
+
447
+ if test .skipOmitEmpty {
448
+ continue
449
+ }
450
+ t .Run (fmt .Sprintf ("%v vs %v (omitempty)" , test .pointer , test .optional ), func (t * testing.T ) {
451
+ wrapPointer := WrapOmitEmpty [* Sub ]{Sub1 : test .pointer }
452
+ confPointer := confmap .NewFromStringMap (nil )
453
+ require .NoError (t , confPointer .Marshal (wrapPointer ))
454
+
455
+ wrapOptional := WrapOmitEmpty [Optional [Sub ]]{Sub1 : test .optional }
456
+ confOptional := confmap .NewFromStringMap (nil )
457
+ require .NoError (t , confOptional .Marshal (wrapOptional ))
458
+
459
+ assert .Equal (t , confPointer .ToStringMap (), confOptional .ToStringMap ())
460
+ })
461
+ }
462
+ }
0 commit comments