@@ -471,6 +471,143 @@ func TestNullableRequired_UnmarshalJSON(t *testing.T) {
471
471
}
472
472
}
473
473
474
+ type ComplexNullable struct {
475
+ Config nullable.Nullable [Config ] `json:"config,omitempty"`
476
+ Location nullable.Nullable [string ] `json:"location"`
477
+ NodeCount nullable.Nullable [int ] `json:"node_count,omitempty"`
478
+ }
479
+
480
+ type Config struct {
481
+ CPU nullable.Nullable [string ] `json:"cpu,omitempty"`
482
+ RAM nullable.Nullable [string ] `json:"ram,omitempty"`
483
+ }
484
+
485
+ func TestComplexNullable (t * testing.T ) {
486
+ type testCase struct {
487
+ name string
488
+ jsonInput []byte
489
+ assert func (obj ComplexNullable , t * testing.T )
490
+ wantNull bool
491
+ wantSpecified bool
492
+ }
493
+ tests := []testCase {
494
+ {
495
+ name : "complex object: empty value" ,
496
+ jsonInput : []byte (`{}` ),
497
+ assert : func (obj ComplexNullable , t * testing.T ) {
498
+ t .Helper ()
499
+
500
+ assert .Equalf (t , false , obj .Config .IsSpecified (), "config should not be set" )
501
+ assert .Equalf (t , false , obj .Config .IsNull (), "config should not be null" )
502
+
503
+ assert .Equalf (t , false , obj .NodeCount .IsSpecified (), "node count should not be set" )
504
+ assert .Equalf (t , false , obj .NodeCount .IsNull (), "node count should not be null" )
505
+
506
+ assert .Equalf (t , false , obj .Location .IsSpecified (), "location should not be set" )
507
+ assert .Equalf (t , false , obj .Location .IsNull (), "location should not be null" )
508
+ },
509
+ },
510
+ {
511
+ name : "complex object: empty config value" ,
512
+ jsonInput : []byte (`{"config":{}}` ),
513
+ assert : func (obj ComplexNullable , t * testing.T ) {
514
+ t .Helper ()
515
+
516
+ assert .Equalf (t , true , obj .Config .IsSpecified (), "config should be set" )
517
+ assert .Equalf (t , false , obj .Config .IsNull (), "config should not be null" )
518
+
519
+ gotConfig , err := obj .Config .Get ()
520
+ require .NoError (t , err )
521
+
522
+ assert .Equalf (t , false , gotConfig .CPU .IsSpecified (), "cpu should not be set" )
523
+ assert .Equalf (t , false , gotConfig .CPU .IsNull (), "cpu should not be null" )
524
+
525
+ assert .Equalf (t , false , gotConfig .RAM .IsSpecified (), "ram should not be set" )
526
+ assert .Equalf (t , false , gotConfig .RAM .IsNull (), "ram should not be null" )
527
+ },
528
+ },
529
+
530
+ {
531
+ name : "complex object: setting only cpu config value" ,
532
+ jsonInput : []byte (`{"config":{"cpu":"500"}}` ),
533
+ assert : func (obj ComplexNullable , t * testing.T ) {
534
+ t .Helper ()
535
+
536
+ assert .Equalf (t , true , obj .Config .IsSpecified (), "config should be set" )
537
+ assert .Equalf (t , false , obj .Config .IsNull (), "config should not be null" )
538
+
539
+ gotConfig , err := obj .Config .Get ()
540
+ require .NoError (t , err )
541
+
542
+ assert .Equalf (t , true , gotConfig .CPU .IsSpecified (), "cpu should be set" )
543
+ assert .Equalf (t , false , gotConfig .CPU .IsNull (), "cpu should not be null" )
544
+
545
+ assert .Equalf (t , false , gotConfig .RAM .IsSpecified (), "ram should not be set" )
546
+ assert .Equalf (t , false , gotConfig .RAM .IsNull (), "ram should not be null" )
547
+ },
548
+ },
549
+
550
+ {
551
+ name : "complex object: setting only ram config value" ,
552
+ jsonInput : []byte (`{"config":{"ram":"1024"}}` ),
553
+ assert : func (obj ComplexNullable , t * testing.T ) {
554
+ t .Helper ()
555
+
556
+ assert .Equalf (t , true , obj .Config .IsSpecified (), "config should be set" )
557
+ assert .Equalf (t , false , obj .Config .IsNull (), "config should not be null" )
558
+
559
+ gotConfig , err := obj .Config .Get ()
560
+ require .NoError (t , err )
561
+
562
+ assert .Equalf (t , false , gotConfig .CPU .IsSpecified (), "cpu should not be set" )
563
+ assert .Equalf (t , false , gotConfig .CPU .IsNull (), "cpu should not be null" )
564
+
565
+ assert .Equalf (t , true , gotConfig .RAM .IsSpecified (), "ram should be set" )
566
+ assert .Equalf (t , false , gotConfig .RAM .IsNull (), "ram should not be null" )
567
+ },
568
+ },
569
+
570
+ {
571
+ name : "complex object: setting config to null" ,
572
+ jsonInput : []byte (`{"config":null}` ),
573
+ assert : func (obj ComplexNullable , t * testing.T ) {
574
+ t .Helper ()
575
+
576
+ assert .Equalf (t , true , obj .Config .IsSpecified (), "config should be set" )
577
+ assert .Equalf (t , true , obj .Config .IsNull (), "config should not be null" )
578
+ },
579
+ },
580
+
581
+ {
582
+ name : "complex object: setting only cpu config to null" ,
583
+ jsonInput : []byte (`{"config":{"cpu":null}}` ),
584
+ assert : func (obj ComplexNullable , t * testing.T ) {
585
+ t .Helper ()
586
+
587
+ assert .Equalf (t , true , obj .Config .IsSpecified (), "config should be set" )
588
+ assert .Equalf (t , false , obj .Config .IsNull (), "config should not be null" )
589
+
590
+ gotConfig , err := obj .Config .Get ()
591
+ require .NoError (t , err )
592
+
593
+ assert .Equalf (t , true , gotConfig .CPU .IsSpecified (), "cpu should be set" )
594
+ assert .Equalf (t , true , gotConfig .CPU .IsNull (), "cpu should be null" )
595
+
596
+ assert .Equalf (t , false , gotConfig .RAM .IsSpecified (), "ram should not be set" )
597
+ assert .Equalf (t , false , gotConfig .RAM .IsNull (), "ram should not be null" )
598
+ },
599
+ },
600
+ }
601
+ for _ , tt := range tests {
602
+ t .Run (tt .name , func (t * testing.T ) {
603
+ var obj ComplexNullable
604
+ err := json .Unmarshal (tt .jsonInput , & obj )
605
+ require .NoError (t , err )
606
+ tt .assert (obj , t )
607
+ })
608
+ }
609
+ }
610
+
474
611
// Idempotency tests for nullable and optional
475
612
type StringNullableOptional struct {
476
613
ID nullable.Nullable [string ] `json:"id,omitempty"`
0 commit comments