@@ -23,6 +23,7 @@ import {
2323 toIdSchema ,
2424 toPathSchema ,
2525 guessType ,
26+ mergeSchemas ,
2627} from "../src/utils" ;
2728
2829describe ( "utils" , ( ) => {
@@ -1058,6 +1059,123 @@ describe("utils", () => {
10581059 } ) ;
10591060 } ) ;
10601061
1062+ describe ( "mergeSchemas()" , ( ) => {
1063+ it ( "shouldn't mutate the provided objects" , ( ) => {
1064+ const obj1 = { a : 1 } ;
1065+ mergeSchemas ( obj1 , { b : 2 } ) ;
1066+ expect ( obj1 ) . eql ( { a : 1 } ) ;
1067+ } ) ;
1068+
1069+ it ( "should merge two one-level deep objects" , ( ) => {
1070+ expect ( mergeSchemas ( { a : 1 } , { b : 2 } ) ) . eql ( { a : 1 , b : 2 } ) ;
1071+ } ) ;
1072+
1073+ it ( "should override the first object with the values from the second" , ( ) => {
1074+ expect ( mergeSchemas ( { a : 1 } , { a : 2 } ) ) . eql ( { a : 2 } ) ;
1075+ } ) ;
1076+
1077+ it ( "should override non-existing values of the first object with the values from the second" , ( ) => {
1078+ expect ( mergeSchemas ( { a : { b : undefined } } , { a : { b : { c : 1 } } } ) ) . eql (
1079+ { a : { b : { c : 1 } } }
1080+ ) ;
1081+ } ) ;
1082+
1083+ it ( "should recursively merge deeply nested objects" , ( ) => {
1084+ const obj1 = {
1085+ a : 1 ,
1086+ b : {
1087+ c : 3 ,
1088+ d : [ 1 , 2 , 3 ] ,
1089+ e : { f : { g : 1 } } ,
1090+ } ,
1091+ c : 2 ,
1092+ } ;
1093+ const obj2 = {
1094+ a : 1 ,
1095+ b : {
1096+ d : [ 3 , 2 , 1 ] ,
1097+ e : { f : { h : 2 } } ,
1098+ g : 1 ,
1099+ } ,
1100+ c : 3 ,
1101+ } ;
1102+ const expected = {
1103+ a : 1 ,
1104+ b : {
1105+ c : 3 ,
1106+ d : [ 3 , 2 , 1 ] ,
1107+ e : { f : { g : 1 , h : 2 } } ,
1108+ g : 1 ,
1109+ } ,
1110+ c : 3 ,
1111+ } ;
1112+ expect ( mergeSchemas ( obj1 , obj2 ) ) . eql ( expected ) ;
1113+ } ) ;
1114+
1115+ it ( "should recursively merge File objects" , ( ) => {
1116+ const file = new File ( [ "test" ] , "test.txt" ) ;
1117+ const obj1 = {
1118+ a : { } ,
1119+ } ;
1120+ const obj2 = {
1121+ a : file ,
1122+ } ;
1123+ expect ( mergeSchemas ( obj1 , obj2 ) . a ) . instanceOf ( File ) ;
1124+ } ) ;
1125+
1126+ describe ( "arrays" , ( ) => {
1127+ it ( "should not concat arrays" , ( ) => {
1128+ const obj1 = { a : [ 1 ] } ;
1129+ const obj2 = { a : [ 2 ] } ;
1130+
1131+ expect ( mergeSchemas ( obj1 , obj2 ) ) . eql ( { a : [ 2 ] } ) ;
1132+ } ) ;
1133+
1134+ it ( "should concat arrays under 'required' keyword" , ( ) => {
1135+ const obj1 = { type : "object" , required : [ 1 ] } ;
1136+ const obj2 = { type : "object" , required : [ 2 ] } ;
1137+
1138+ expect ( mergeSchemas ( obj1 , obj2 ) ) . eql ( {
1139+ type : "object" ,
1140+ required : [ 1 , 2 ] ,
1141+ } ) ;
1142+ } ) ;
1143+
1144+ it ( "should concat arrays under 'required' keyword when one of the schemas is an object type" , ( ) => {
1145+ const obj1 = { type : "object" , required : [ 1 ] } ;
1146+ const obj2 = { required : [ 2 ] } ;
1147+
1148+ expect ( mergeSchemas ( obj1 , obj2 ) ) . eql ( {
1149+ type : "object" ,
1150+ required : [ 1 , 2 ] ,
1151+ } ) ;
1152+ } ) ;
1153+
1154+ it ( "should concat nested arrays under 'required' keyword" , ( ) => {
1155+ const obj1 = { a : { type : "object" , required : [ 1 ] } } ;
1156+ const obj2 = { a : { type : "object" , required : [ 2 ] } } ;
1157+
1158+ expect ( mergeSchemas ( obj1 , obj2 ) ) . eql ( {
1159+ a : { type : "object" , required : [ 1 , 2 ] } ,
1160+ } ) ;
1161+ } ) ;
1162+
1163+ it ( "should not include duplicate values when concatting arrays under 'required' keyword" , ( ) => {
1164+ const obj1 = { type : "object" , required : [ 1 ] } ;
1165+ const obj2 = { type : "object" , required : [ 1 ] } ;
1166+
1167+ expect ( mergeSchemas ( obj1 , obj2 ) ) . eql ( { type : "object" , required : [ 1 ] } ) ;
1168+ } ) ;
1169+
1170+ it ( "should not concat arrays under 'required' keyword that are not under an object type" , ( ) => {
1171+ const obj1 = { required : [ 1 ] } ;
1172+ const obj2 = { required : [ 2 ] } ;
1173+
1174+ expect ( mergeSchemas ( obj1 , obj2 ) ) . eql ( { required : [ 2 ] } ) ;
1175+ } ) ;
1176+ } ) ;
1177+ } ) ;
1178+
10611179 describe ( "retrieveSchema()" , ( ) => {
10621180 it ( "should 'resolve' a schema which contains definitions" , ( ) => {
10631181 const schema = { $ref : "#/definitions/address" } ;
@@ -1320,6 +1438,35 @@ describe("utils", () => {
13201438 required : [ "a" , "b" ] ,
13211439 } ) ;
13221440 } ) ;
1441+ it ( "should not concat enum properties, but should concat 'required' properties" , ( ) => {
1442+ const schema = {
1443+ type : "object" ,
1444+ properties : {
1445+ a : { type : "string" , enum : [ "FOO" , "BAR" , "BAZ" ] } ,
1446+ b : { type : "string" , enum : [ "GREEN" , "BLUE" , "RED" ] } ,
1447+ } ,
1448+ required : [ "a" ] ,
1449+ dependencies : {
1450+ a : {
1451+ properties : {
1452+ a : { enum : [ "FOO" ] } ,
1453+ b : { enum : [ "BLUE" ] } ,
1454+ } ,
1455+ required : [ "a" , "b" ] ,
1456+ } ,
1457+ } ,
1458+ } ;
1459+ const definitions = { } ;
1460+ const formData = { a : "FOO" } ;
1461+ expect ( retrieveSchema ( schema , definitions , formData ) ) . eql ( {
1462+ type : "object" ,
1463+ properties : {
1464+ a : { type : "string" , enum : [ "FOO" ] } ,
1465+ b : { type : "string" , enum : [ "BLUE" ] } ,
1466+ } ,
1467+ required : [ "a" , "b" ] ,
1468+ } ) ;
1469+ } ) ;
13231470 } ) ;
13241471
13251472 describe ( "with $ref in dependency" , ( ) => {
0 commit comments