@@ -723,6 +723,198 @@ func TestValueIsKnown(t *testing.T) {
723723 }
724724}
725725
726+ func TestValueIsNull (t * testing.T ) {
727+ t .Parallel ()
728+ type testCase struct {
729+ value Value
730+ expectedIsNull bool
731+ expectedIsFullyNull bool
732+ }
733+
734+ simpleObjectTyp := Object {
735+ AttributeTypes : map [string ]Type {
736+ "capacity" : Number ,
737+ },
738+ OptionalAttributes : map [string ]struct {}{
739+ "capacity" : {},
740+ },
741+ }
742+
743+ simpleListTyp := List {
744+ ElementType : String ,
745+ }
746+
747+ simpleSetTyp := Set {
748+ ElementType : String ,
749+ }
750+
751+ networkTyp := Object {
752+ AttributeTypes : map [string ]Type {
753+ "name" : String ,
754+ "speed" : Number ,
755+ "labels" : simpleListTyp ,
756+ },
757+ }
758+
759+ objectTyp := Object {
760+ AttributeTypes : map [string ]Type {
761+ "id" : String ,
762+ "network" : networkTyp ,
763+ },
764+ }
765+
766+ listTyp := List {
767+ ElementType : networkTyp ,
768+ }
769+
770+ tests := map [string ]testCase {
771+ "primitive" : {
772+ value : NewValue (Number , 990 ),
773+ expectedIsNull : false ,
774+ expectedIsFullyNull : false ,
775+ },
776+ "primitive-null" : {
777+ value : NewValue (Number , nil ),
778+ expectedIsNull : true ,
779+ expectedIsFullyNull : true ,
780+ },
781+ "dynamic" : {
782+ value : NewValue (DynamicPseudoType , "hello" ),
783+ expectedIsNull : false ,
784+ expectedIsFullyNull : false ,
785+ },
786+ "dynamic-null" : {
787+ value : NewValue (DynamicPseudoType , nil ),
788+ expectedIsNull : true ,
789+ expectedIsFullyNull : true ,
790+ },
791+ "simple-object" : {
792+ value : NewValue (simpleObjectTyp , map [string ]Value {"capacity" : NewValue (Number , 4096 )}),
793+ expectedIsNull : false ,
794+ expectedIsFullyNull : false ,
795+ },
796+ "simple-object-null" : {
797+ value : NewValue (simpleObjectTyp , nil ),
798+ expectedIsNull : true ,
799+ expectedIsFullyNull : true ,
800+ },
801+ "simple-object-with-empty-attributes-map" : {
802+ value : NewValue (simpleObjectTyp , map [string ]Value {}),
803+ expectedIsNull : false ,
804+ expectedIsFullyNull : true ,
805+ },
806+ "simple-object-with-nil-primitive" : {
807+ value : NewValue (simpleObjectTyp , map [string ]Value {"capacity" : NewValue (Number , nil )}),
808+ expectedIsNull : false ,
809+ expectedIsFullyNull : true ,
810+ },
811+ "object-with-no-nils" : {
812+ value : NewValue (objectTyp , map [string ]Value {
813+ "id" : NewValue (String , "#00decaf" ),
814+ "network" : NewValue (networkTyp , map [string ]Value {
815+ "name" : NewValue (String , "eth0" ),
816+ "speed" : NewValue (Number , 1000000000 ),
817+ "labels" : NewValue (simpleListTyp , []Value {
818+ NewValue (String , "connected" ),
819+ }),
820+ }),
821+ }),
822+ expectedIsNull : false ,
823+ expectedIsFullyNull : false ,
824+ },
825+ "object-with-shallow-nils" : {
826+ value : NewValue (objectTyp , map [string ]Value {
827+ "id" : NewValue (String , nil ),
828+ "network" : NewValue (networkTyp , nil ),
829+ }),
830+ expectedIsNull : false ,
831+ expectedIsFullyNull : true ,
832+ },
833+ "object-with-deep-nils" : {
834+ value : NewValue (objectTyp , map [string ]Value {
835+ "id" : NewValue (String , nil ),
836+ "network" : NewValue (networkTyp , map [string ]Value {
837+ "name" : NewValue (String , nil ),
838+ "speed" : NewValue (Number , nil ),
839+ "labels" : NewValue (simpleListTyp , []Value {
840+ NewValue (String , nil ),
841+ }),
842+ }),
843+ }),
844+ expectedIsNull : false ,
845+ expectedIsFullyNull : true ,
846+ },
847+ "object-with-some-nils" : {
848+ value : NewValue (objectTyp , map [string ]Value {
849+ "id" : NewValue (String , nil ),
850+ "network" : NewValue (networkTyp , map [string ]Value {
851+ "name" : NewValue (String , nil ),
852+ "speed" : NewValue (Number , 1000 ),
853+ "labels" : NewValue (simpleListTyp , []Value {
854+ NewValue (String , nil ),
855+ }),
856+ }),
857+ }),
858+ expectedIsNull : false ,
859+ expectedIsFullyNull : false ,
860+ },
861+ "simple-list-with-no-nils" : {
862+ value : NewValue (simpleListTyp , []Value {
863+ NewValue (String , "restarting" ),
864+ }),
865+ expectedIsNull : false ,
866+ expectedIsFullyNull : false ,
867+ },
868+ "simple-list-with-some-nils" : {
869+ value : NewValue (simpleListTyp , []Value {
870+ NewValue (String , "east-mars" ),
871+ NewValue (String , "south-mars" ),
872+ NewValue (String , nil ),
873+ }),
874+ expectedIsNull : false ,
875+ expectedIsFullyNull : false ,
876+ },
877+ "simple-list-with-shallow-nils" : {
878+ value : NewValue (simpleListTyp , []Value {
879+ NewValue (String , nil ),
880+ }),
881+ expectedIsNull : false ,
882+ expectedIsFullyNull : true ,
883+ },
884+ "list-with-deep-nils" : {
885+ value : NewValue (listTyp , []Value {
886+ NewValue (networkTyp , nil ),
887+ }),
888+ expectedIsNull : false ,
889+ expectedIsFullyNull : true ,
890+ },
891+ "simple-set-with-shallow-nils" : {
892+ value : NewValue (simpleSetTyp , []Value {
893+ NewValue (String , nil ),
894+ }),
895+ expectedIsNull : false ,
896+ expectedIsFullyNull : true ,
897+ },
898+ }
899+
900+ for name , test := range tests {
901+ t .Run (name , func (t * testing.T ) {
902+ t .Parallel ()
903+
904+ actualIsNull := test .value .IsNull ()
905+ actualIsFullyNull := test .value .IsFullyNull ()
906+
907+ if test .expectedIsNull != actualIsNull {
908+ t .Errorf ("expected IsNull() to be %v; actual: %v" , test .expectedIsNull , actualIsNull )
909+ }
910+
911+ if test .expectedIsFullyNull != actualIsFullyNull {
912+ t .Errorf ("expected IsFullyNull() to be %v; actual: %v" , test .expectedIsNull , actualIsNull )
913+ }
914+ })
915+ }
916+ }
917+
726918func TestValueEqual (t * testing.T ) {
727919 t .Parallel ()
728920 type testCase struct {
0 commit comments