@@ -3,10 +3,11 @@ package types
3
3
import (
4
4
"encoding/json"
5
5
"fmt"
6
+ "testing"
7
+
6
8
"github.com/oapi-codegen/nullable"
7
9
"github.com/stretchr/testify/assert"
8
10
"github.com/stretchr/testify/require"
9
- "testing"
10
11
)
11
12
12
13
type SimpleStringNullableRequired struct {
@@ -279,55 +280,54 @@ func TestNullableOptional_UnmarshalJSON(t *testing.T) {
279
280
type testCase struct {
280
281
name string
281
282
json []byte
282
- assert func (obj SimpleIntNullableOptional , t * testing.T )
283
+ assert func (t * testing.T , obj SimpleIntNullableOptional )
283
284
}
284
285
tests := []testCase {
285
286
{
286
287
name : "when not provided" ,
287
288
json : []byte (`{}` ),
288
- assert : func (obj SimpleIntNullableOptional , t * testing.T ) {
289
+ assert : func (t * testing.T , obj SimpleIntNullableOptional ) {
289
290
t .Helper ()
290
291
291
- assert .Equalf ( t , false , obj .ReplicaCount .IsSpecified (), "replica count should not be set" )
292
- assert .Equalf ( t , false , obj .ReplicaCount .IsNull (), "replica count should not be null" )
292
+ assert .Falsef ( t , obj .ReplicaCount .IsSpecified (), "replica count should not be set" )
293
+ assert .Falsef ( t , obj .ReplicaCount .IsNull (), "replica count should not be null" )
293
294
},
294
295
},
295
296
296
297
{
297
298
name : "when explicitly set to zero value" ,
298
299
json : []byte (`{"replica_count":0}` ),
299
- assert : func (obj SimpleIntNullableOptional , t * testing.T ) {
300
+ assert : func (t * testing.T , obj SimpleIntNullableOptional ) {
300
301
t .Helper ()
301
302
302
- assert .Equalf ( t , true , obj .ReplicaCount .IsSpecified (), "replica count should be set" )
303
- assert .Equalf ( t , false , obj .ReplicaCount .IsNull (), "replica count should not be null" )
303
+ assert .Truef ( t , obj .ReplicaCount .IsSpecified (), "replica count should be set" )
304
+ assert .Falsef ( t , obj .ReplicaCount .IsNull (), "replica count should not be null" )
304
305
305
306
val , err := obj .ReplicaCount .Get ()
306
307
require .NoError (t , err )
307
308
assert .Equalf (t , 0 , val , "replica count value should be 0" )
308
-
309
309
},
310
310
},
311
311
312
312
{
313
313
name : "when explicitly set to null value" ,
314
314
json : []byte (`{"replica_count":null}` ),
315
- assert : func (obj SimpleIntNullableOptional , t * testing.T ) {
315
+ assert : func (t * testing.T , obj SimpleIntNullableOptional ) {
316
316
t .Helper ()
317
317
318
- assert .Equalf ( t , true , obj .ReplicaCount .IsSpecified (), "replica count should be set" )
319
- assert .Equalf ( t , true , obj .ReplicaCount .IsNull (), "replica count should be null" )
318
+ assert .Truef ( t , obj .ReplicaCount .IsSpecified (), "replica count should be set" )
319
+ assert .Truef ( t , obj .ReplicaCount .IsNull (), "replica count should be null" )
320
320
},
321
321
},
322
322
323
323
{
324
324
name : "when explicitly set to a specific value" ,
325
325
json : []byte (`{"replica_count":5}` ),
326
- assert : func (obj SimpleIntNullableOptional , t * testing.T ) {
326
+ assert : func (t * testing.T , obj SimpleIntNullableOptional ) {
327
327
t .Helper ()
328
328
329
- assert .Equalf (t , true , obj .ReplicaCount .IsSpecified (), "replica count should not be null " )
330
- assert .Equalf ( t , false , obj .ReplicaCount .IsNull (), "replica count should not be null" )
329
+ assert .Truef (t , obj .ReplicaCount .IsSpecified (), "replica count should be set " )
330
+ assert .Falsef ( t , obj .ReplicaCount .IsNull (), "replica count should not be null" )
331
331
332
332
val , err := obj .ReplicaCount .Get ()
333
333
require .NoError (t , err )
@@ -340,7 +340,8 @@ func TestNullableOptional_UnmarshalJSON(t *testing.T) {
340
340
var obj SimpleIntNullableOptional
341
341
err := json .Unmarshal (tt .json , & obj )
342
342
require .NoError (t , err )
343
- tt .assert (obj , t )
343
+
344
+ tt .assert (t , obj )
344
345
})
345
346
}
346
347
}
@@ -403,7 +404,7 @@ func TestNullableRequired_UnmarshalJSON(t *testing.T) {
403
404
type testCase struct {
404
405
name string
405
406
json []byte
406
- assert func (obj SimpleIntNullableRequired , t * testing.T )
407
+ assert func (t * testing.T , obj SimpleIntNullableRequired )
407
408
}
408
409
tests := []testCase {
409
410
{
@@ -412,22 +413,22 @@ func TestNullableRequired_UnmarshalJSON(t *testing.T) {
412
413
// the behaviour
413
414
name : "when not provided" ,
414
415
json : []byte (`{}` ),
415
- assert : func (obj SimpleIntNullableRequired , t * testing.T ) {
416
+ assert : func (t * testing.T , obj SimpleIntNullableRequired ) {
416
417
t .Helper ()
417
418
418
- assert .Equalf ( t , false , obj .ReplicaCount .IsNull (), "replica count should not be null" )
419
- assert .Equalf ( t , false , obj .ReplicaCount .IsSpecified (), "replica count should not be set" )
419
+ assert .Falsef ( t , obj .ReplicaCount .IsNull (), "replica count should not be null" )
420
+ assert .Falsef ( t , obj .ReplicaCount .IsSpecified (), "replica count should not be set" )
420
421
},
421
422
},
422
423
423
424
{
424
425
name : "when explicitly set to zero value" ,
425
426
json : []byte (`{"replica_count":0}` ),
426
- assert : func (obj SimpleIntNullableRequired , t * testing.T ) {
427
+ assert : func (t * testing.T , obj SimpleIntNullableRequired ) {
427
428
t .Helper ()
428
429
429
- assert .Equalf ( t , false , obj .ReplicaCount .IsNull (), "replica count should not be null" )
430
- assert .Equalf ( t , true , obj .ReplicaCount .IsSpecified (), "replica count should be set" )
430
+ assert .Falsef ( t , obj .ReplicaCount .IsNull (), "replica count should not be null" )
431
+ assert .Truef ( t , obj .ReplicaCount .IsSpecified (), "replica count should be set" )
431
432
432
433
val , err := obj .ReplicaCount .Get ()
433
434
require .NoError (t , err )
@@ -438,22 +439,22 @@ func TestNullableRequired_UnmarshalJSON(t *testing.T) {
438
439
{
439
440
name : "when explicitly set to null value" ,
440
441
json : []byte (`{"replica_count":null}` ),
441
- assert : func (obj SimpleIntNullableRequired , t * testing.T ) {
442
+ assert : func (t * testing.T , obj SimpleIntNullableRequired ) {
442
443
t .Helper ()
443
444
444
- assert .Equalf ( t , true , obj .ReplicaCount .IsSpecified (), "replica count should be set" )
445
- assert .Equalf ( t , true , obj .ReplicaCount .IsNull (), "replica count should be null" )
445
+ assert .Truef ( t , obj .ReplicaCount .IsSpecified (), "replica count should be set" )
446
+ assert .Truef ( t , obj .ReplicaCount .IsNull (), "replica count should be null" )
446
447
},
447
448
},
448
449
449
450
{
450
451
name : "when explicitly set to a specific value" ,
451
452
json : []byte (`{"replica_count":5}` ),
452
- assert : func (obj SimpleIntNullableRequired , t * testing.T ) {
453
+ assert : func (t * testing.T , obj SimpleIntNullableRequired ) {
453
454
t .Helper ()
454
455
455
- assert .Equalf ( t , false , obj .ReplicaCount .IsNull (), "replica count should not be null" )
456
- assert .Equalf ( t , true , obj .ReplicaCount .IsSpecified (), "replica count should be set" )
456
+ assert .Falsef ( t , obj .ReplicaCount .IsNull (), "replica count should not be null" )
457
+ assert .Truef ( t , obj .ReplicaCount .IsSpecified (), "replica count should be set" )
457
458
458
459
val , err := obj .ReplicaCount .Get ()
459
460
require .NoError (t , err )
@@ -466,35 +467,179 @@ func TestNullableRequired_UnmarshalJSON(t *testing.T) {
466
467
var obj SimpleIntNullableRequired
467
468
err := json .Unmarshal (tt .json , & obj )
468
469
require .NoError (t , err )
469
- tt .assert (obj , t )
470
+
471
+ tt .assert (t , obj )
472
+ })
473
+ }
474
+ }
475
+
476
+ type ComplexNullable struct {
477
+ Config nullable.Nullable [Config ] `json:"config,omitempty"`
478
+ Location nullable.Nullable [string ] `json:"location"`
479
+ NodeCount nullable.Nullable [int ] `json:"node_count,omitempty"`
480
+ }
481
+
482
+ type Config struct {
483
+ CPU nullable.Nullable [string ] `json:"cpu,omitempty"`
484
+ RAM nullable.Nullable [string ] `json:"ram,omitempty"`
485
+ }
486
+
487
+ func TestComplexNullable (t * testing.T ) {
488
+ type testCase struct {
489
+ name string
490
+ jsonInput []byte
491
+ assert func (t * testing.T , obj ComplexNullable )
492
+ }
493
+ tests := []testCase {
494
+ {
495
+ name : "complex object: empty value" ,
496
+ jsonInput : []byte (`{}` ),
497
+ assert : func (t * testing.T , obj ComplexNullable ) {
498
+ t .Helper ()
499
+
500
+ assert .Falsef (t , obj .Config .IsSpecified (), "config should not be set" )
501
+ assert .Falsef (t , obj .Config .IsNull (), "config should not be null" )
502
+
503
+ assert .Falsef (t , obj .NodeCount .IsSpecified (), "node count should not be set" )
504
+ assert .Falsef (t , obj .NodeCount .IsNull (), "node count should not be null" )
505
+
506
+ assert .Falsef (t , obj .Location .IsSpecified (), "location should not be set" )
507
+ assert .Falsef (t , 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 (t * testing.T , obj ComplexNullable ) {
514
+ t .Helper ()
515
+
516
+ assert .Truef (t , obj .Config .IsSpecified (), "config should be set" )
517
+ assert .Falsef (t , obj .Config .IsNull (), "config should not be null" )
518
+
519
+ gotConfig , err := obj .Config .Get ()
520
+ require .NoError (t , err )
521
+
522
+ assert .Falsef (t , gotConfig .CPU .IsSpecified (), "cpu should not be set" )
523
+ assert .Falsef (t , gotConfig .CPU .IsNull (), "cpu should not be null" )
524
+
525
+ assert .Falsef (t , gotConfig .RAM .IsSpecified (), "ram should not be set" )
526
+ assert .Falsef (t , 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 (t * testing.T , obj ComplexNullable ) {
534
+ t .Helper ()
535
+
536
+ assert .Truef (t , obj .Config .IsSpecified (), "config should be set" )
537
+ assert .Falsef (t , obj .Config .IsNull (), "config should not be null" )
538
+
539
+ gotConfig , err := obj .Config .Get ()
540
+ require .NoError (t , err )
541
+
542
+ assert .Truef (t , gotConfig .CPU .IsSpecified (), "cpu should be set" )
543
+ assert .Falsef (t , gotConfig .CPU .IsNull (), "cpu should not be null" )
544
+
545
+ assert .Falsef (t , gotConfig .RAM .IsSpecified (), "ram should not be set" )
546
+ assert .Falsef (t , 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 (t * testing.T , obj ComplexNullable ) {
554
+ t .Helper ()
555
+
556
+ assert .Truef (t , obj .Config .IsSpecified (), "config should be set" )
557
+ assert .Falsef (t , obj .Config .IsNull (), "config should not be null" )
558
+
559
+ gotConfig , err := obj .Config .Get ()
560
+ require .NoError (t , err )
561
+
562
+ assert .Falsef (t , gotConfig .CPU .IsSpecified (), "cpu should not be set" )
563
+ assert .Falsef (t , gotConfig .CPU .IsNull (), "cpu should not be null" )
564
+
565
+ assert .Truef (t , gotConfig .RAM .IsSpecified (), "ram should be set" )
566
+ assert .Falsef (t , 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 (t * testing.T , obj ComplexNullable ) {
574
+ t .Helper ()
575
+
576
+ assert .Truef (t , obj .Config .IsSpecified (), "config should be set" )
577
+ assert .Truef (t , 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 (t * testing.T , obj ComplexNullable ) {
585
+ t .Helper ()
586
+
587
+ assert .Truef (t , obj .Config .IsSpecified (), "config should be set" )
588
+ assert .Falsef (t , obj .Config .IsNull (), "config should not be null" )
589
+
590
+ gotConfig , err := obj .Config .Get ()
591
+ require .NoError (t , err )
592
+
593
+ assert .Truef (t , gotConfig .CPU .IsSpecified (), "cpu should be set" )
594
+ assert .Truef (t , gotConfig .CPU .IsNull (), "cpu should be null" )
595
+
596
+ assert .Falsef (t , gotConfig .RAM .IsSpecified (), "ram should not be set" )
597
+ assert .Falsef (t , 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
+
607
+ tt .assert (t , obj )
470
608
})
471
609
}
472
610
}
473
611
474
- // Idempotency tests for nullable and optional
612
+ // Tests to validate that repeated unmarshal and marshal should not change
613
+ // the JSON for optional and nullable.
475
614
type StringNullableOptional struct {
476
615
ID nullable.Nullable [string ] `json:"id,omitempty"`
477
616
Name nullable.Nullable [string ] `json:"name,omitempty"`
478
617
Address nullable.Nullable [string ] `json:"address,omitempty"`
479
618
}
480
619
481
- func TestNullableOptionalUnmarshalIdempotency (t * testing.T ) {
620
+ func TestNullableOptionalUnmarshal (t * testing.T ) {
482
621
var obj1 StringNullableOptional
483
622
originalJSON1 := []byte (`{}` )
623
+
484
624
err := json .Unmarshal (originalJSON1 , & obj1 )
485
625
require .NoError (t , err )
486
626
newJSON1 , err := json .Marshal (obj1 )
627
+ require .NoError (t , err )
628
+
487
629
require .Equal (t , originalJSON1 , newJSON1 )
488
630
489
631
var obj2 StringNullableOptional
490
632
originalJSON2 := []byte (`{"id":"12esd412"}` )
491
- err2 := json .Unmarshal (originalJSON2 , & obj2 )
492
- require .NoError (t , err2 )
493
- newJSON2 , err2 := json .Marshal (obj2 )
633
+
634
+ err = json .Unmarshal (originalJSON2 , & obj2 )
635
+ require .NoError (t , err )
636
+ newJSON2 , err := json .Marshal (obj2 )
637
+ require .NoError (t , err )
638
+
494
639
require .Equal (t , originalJSON2 , newJSON2 )
495
640
}
496
641
497
- func TestNullableOptionalMarshalIdempotency (t * testing.T ) {
642
+ func TestNullableOptionalMarshal (t * testing.T ) {
498
643
obj1 := StringNullableOptional {
499
644
ID : nullable.Nullable [string ]{
500
645
true : "id-1" ,
@@ -507,8 +652,8 @@ func TestNullableOptionalMarshalIdempotency(t *testing.T) {
507
652
},
508
653
}
509
654
expectedJSON1 := []byte (`{"id":"id-1","name":"","address":null}` )
510
- gotJSON1 , err1 := json .Marshal (obj1 )
511
- require .NoError (t , err1 )
655
+ gotJSON1 , err := json .Marshal (obj1 )
656
+ require .NoError (t , err )
512
657
require .Equal (t , expectedJSON1 , gotJSON1 )
513
658
514
659
obj2 := StringNullableOptional {
@@ -520,7 +665,7 @@ func TestNullableOptionalMarshalIdempotency(t *testing.T) {
520
665
},
521
666
}
522
667
expectedJSON2 := []byte (`{"id":"id-1","address":null}` )
523
- gotJSON2 , err2 := json .Marshal (obj2 )
524
- require .NoError (t , err2 )
668
+ gotJSON2 , err := json .Marshal (obj2 )
669
+ require .NoError (t , err )
525
670
require .Equal (t , expectedJSON2 , gotJSON2 )
526
671
}
0 commit comments