@@ -1926,5 +1926,349 @@ export default function retrieveSchemaTest(testValidator: TestValidatorType) {
19261926 ] ) ;
19271927 } ) ;
19281928 } ) ;
1929+ describe ( 'resolveReference() with experimental_customMergeAllOf' , ( ) => {
1930+ it ( 'should pass experimental_customMergeAllOf parameter to retrieveSchemaInternal' , ( ) => {
1931+ const schema : RJSFSchema = {
1932+ $ref : '#/definitions/testRef' ,
1933+ allOf : [
1934+ {
1935+ type : 'object' ,
1936+ properties : {
1937+ string : { type : 'string' } ,
1938+ } ,
1939+ } ,
1940+ {
1941+ type : 'object' ,
1942+ properties : {
1943+ number : { type : 'number' } ,
1944+ } ,
1945+ } ,
1946+ ] ,
1947+ } ;
1948+ const rootSchema : RJSFSchema = {
1949+ definitions : {
1950+ testRef : {
1951+ type : 'object' ,
1952+ properties : {
1953+ base : { type : 'string' } ,
1954+ } ,
1955+ } ,
1956+ } ,
1957+ } ;
1958+ const customMergeAllOf = jest . fn ( ) . mockReturnValue ( {
1959+ type : 'object' ,
1960+ properties : {
1961+ base : { type : 'string' } ,
1962+ string : { type : 'string' } ,
1963+ number : { type : 'number' } ,
1964+ } ,
1965+ } ) ;
1966+ const result = retrieveSchema ( testValidator , schema , rootSchema , { } , customMergeAllOf ) ;
1967+ expect ( customMergeAllOf ) . toHaveBeenCalled ( ) ;
1968+ expect ( result ) . toEqual ( {
1969+ type : 'object' ,
1970+ properties : {
1971+ base : { type : 'string' } ,
1972+ string : { type : 'string' } ,
1973+ number : { type : 'number' } ,
1974+ } ,
1975+ } ) ;
1976+ } ) ;
1977+ } ) ;
1978+ describe ( 'resolveDependencies() with experimental_customMergeAllOf' , ( ) => {
1979+ it ( 'should pass experimental_customMergeAllOf parameter through dependency resolution' , ( ) => {
1980+ const schema : RJSFSchema = {
1981+ type : 'object' ,
1982+ properties : {
1983+ a : { type : 'string' } ,
1984+ } ,
1985+ dependencies : {
1986+ a : {
1987+ allOf : [
1988+ {
1989+ type : 'object' ,
1990+ properties : {
1991+ string : { type : 'string' } ,
1992+ } ,
1993+ } ,
1994+ {
1995+ type : 'object' ,
1996+ properties : {
1997+ number : { type : 'number' } ,
1998+ } ,
1999+ } ,
2000+ ] ,
2001+ } ,
2002+ } ,
2003+ } ;
2004+ const rootSchema : RJSFSchema = { definitions : { } } ;
2005+ const formData = { a : 'test' } ;
2006+ const customMergeAllOf = jest . fn ( ) . mockReturnValue ( {
2007+ type : 'object' ,
2008+ properties : {
2009+ string : { type : 'string' } ,
2010+ number : { type : 'number' } ,
2011+ } ,
2012+ } ) ;
2013+ const result = retrieveSchema ( testValidator , schema , rootSchema , formData , customMergeAllOf ) ;
2014+ expect ( customMergeAllOf ) . toHaveBeenCalled ( ) ;
2015+ expect ( result ) . toEqual ( {
2016+ type : 'object' ,
2017+ properties : {
2018+ a : { type : 'string' } ,
2019+ string : { type : 'string' } ,
2020+ number : { type : 'number' } ,
2021+ } ,
2022+ } ) ;
2023+ } ) ;
2024+ } ) ;
2025+ describe ( 'resolveSchema() integration with experimental_customMergeAllOf' , ( ) => {
2026+ it ( 'should properly pass experimental_customMergeAllOf through all resolution paths' , ( ) => {
2027+ const schema : RJSFSchema = {
2028+ $ref : '#/definitions/baseSchema' ,
2029+ dependencies : {
2030+ trigger : {
2031+ allOf : [
2032+ {
2033+ type : 'object' ,
2034+ properties : {
2035+ prop1 : { type : 'string' } ,
2036+ } ,
2037+ } ,
2038+ {
2039+ type : 'object' ,
2040+ properties : {
2041+ prop2 : { type : 'number' } ,
2042+ } ,
2043+ } ,
2044+ ] ,
2045+ } ,
2046+ } ,
2047+ } ;
2048+ const rootSchema : RJSFSchema = {
2049+ definitions : {
2050+ baseSchema : {
2051+ type : 'object' ,
2052+ properties : {
2053+ base : { type : 'string' } ,
2054+ } ,
2055+ allOf : [
2056+ {
2057+ type : 'object' ,
2058+ properties : {
2059+ additional : { type : 'boolean' } ,
2060+ } ,
2061+ } ,
2062+ ] ,
2063+ } ,
2064+ } ,
2065+ } ;
2066+ const formData = { trigger : 'value' } ;
2067+ const customMergeAllOf = jest . fn ( ) . mockImplementation ( ( schema ) => {
2068+ // Custom merge logic that combines all properties
2069+ const allProperties : any = { } ;
2070+ if ( schema . properties ) {
2071+ Object . assign ( allProperties , schema . properties ) ;
2072+ }
2073+ if ( schema . allOf ) {
2074+ schema . allOf . forEach ( ( subSchema : any ) => {
2075+ if ( subSchema . properties ) {
2076+ Object . assign ( allProperties , subSchema . properties ) ;
2077+ }
2078+ } ) ;
2079+ }
2080+ return {
2081+ ...schema ,
2082+ properties : allProperties ,
2083+ allOf : undefined ,
2084+ } ;
2085+ } ) ;
2086+ const result = retrieveSchema ( testValidator , schema , rootSchema , formData , customMergeAllOf ) ;
2087+ // Verify that customMergeAllOf was called multiple times (for different allOf blocks)
2088+ expect ( customMergeAllOf ) . toHaveBeenCalledTimes ( 3 ) ;
2089+ expect ( result ) . toEqual ( {
2090+ type : 'object' ,
2091+ properties : {
2092+ base : { type : 'string' } ,
2093+ additional : { type : 'boolean' } ,
2094+ } ,
2095+ allOf : undefined ,
2096+ } ) ;
2097+ } ) ;
2098+ it ( 'should handle experimental_customMergeAllOf with nested $ref resolution' , ( ) => {
2099+ const schema : RJSFSchema = {
2100+ $ref : '#/definitions/nestedRef' ,
2101+ } ;
2102+ const rootSchema : RJSFSchema = {
2103+ definitions : {
2104+ nestedRef : {
2105+ $ref : '#/definitions/finalSchema' ,
2106+ allOf : [
2107+ {
2108+ type : 'object' ,
2109+ properties : {
2110+ nested : { type : 'string' } ,
2111+ } ,
2112+ } ,
2113+ ] ,
2114+ } ,
2115+ finalSchema : {
2116+ type : 'object' ,
2117+ properties : {
2118+ final : { type : 'number' } ,
2119+ } ,
2120+ } ,
2121+ } ,
2122+ } ;
2123+ const customMergeAllOf = jest . fn ( ) . mockReturnValue ( {
2124+ type : 'object' ,
2125+ properties : {
2126+ final : { type : 'number' } ,
2127+ nested : { type : 'string' } ,
2128+ } ,
2129+ } ) ;
2130+ const result = retrieveSchema ( testValidator , schema , rootSchema , { } , customMergeAllOf ) ;
2131+ expect ( customMergeAllOf ) . toHaveBeenCalled ( ) ;
2132+ expect ( result ) . toEqual ( {
2133+ type : 'object' ,
2134+ properties : {
2135+ final : { type : 'number' } ,
2136+ nested : { type : 'string' } ,
2137+ } ,
2138+ } ) ;
2139+ } ) ;
2140+ } ) ;
2141+ describe ( 'Edge cases for experimental_customMergeAllOf fix' , ( ) => {
2142+ it ( 'should handle undefined experimental_customMergeAllOf parameter gracefully' , ( ) => {
2143+ const schema : RJSFSchema = {
2144+ $ref : '#/definitions/testRef' ,
2145+ dependencies : {
2146+ trigger : {
2147+ allOf : [
2148+ {
2149+ type : 'object' ,
2150+ properties : {
2151+ prop : { type : 'string' } ,
2152+ } ,
2153+ } ,
2154+ ] ,
2155+ } ,
2156+ } ,
2157+ } ;
2158+ const rootSchema : RJSFSchema = {
2159+ definitions : {
2160+ testRef : {
2161+ type : 'object' ,
2162+ properties : {
2163+ base : { type : 'string' } ,
2164+ } ,
2165+ } ,
2166+ } ,
2167+ } ;
2168+ const formData = { trigger : 'value' } ;
2169+ // Test with undefined experimental_customMergeAllOf (should use default mergeAllOf)
2170+ const result = retrieveSchema ( testValidator , schema , rootSchema , formData , undefined ) ;
2171+ expect ( result ) . toEqual ( {
2172+ type : 'object' ,
2173+ properties : {
2174+ base : { type : 'string' } ,
2175+ } ,
2176+ } ) ;
2177+ } ) ;
2178+ it ( 'should handle experimental_customMergeAllOf that throws an error' , ( ) => {
2179+ const schema : RJSFSchema = {
2180+ allOf : [
2181+ {
2182+ type : 'object' ,
2183+ properties : {
2184+ string : { type : 'string' } ,
2185+ } ,
2186+ } ,
2187+ {
2188+ type : 'object' ,
2189+ properties : {
2190+ number : { type : 'number' } ,
2191+ } ,
2192+ } ,
2193+ ] ,
2194+ } ;
2195+ const rootSchema : RJSFSchema = { definitions : { } } ;
2196+ const customMergeAllOf = jest . fn ( ) . mockImplementation ( ( ) => {
2197+ throw new Error ( 'Custom merge failed' ) ;
2198+ } ) ;
2199+ const result = retrieveSchema ( testValidator , schema , rootSchema , { } , customMergeAllOf ) ;
2200+ // Should fall back to default behavior when custom merge fails
2201+ expect ( result ) . toEqual ( { } ) ;
2202+ expect ( consoleWarnSpy ) . toHaveBeenCalledWith ( 'could not merge subschemas in allOf:\n' , expect . any ( Error ) ) ;
2203+ } ) ;
2204+ it ( 'should pass experimental_customMergeAllOf through complex nested resolution chains' , ( ) => {
2205+ const schema : RJSFSchema = {
2206+ $ref : '#/definitions/level1' ,
2207+ } ;
2208+ const rootSchema : RJSFSchema = {
2209+ definitions : {
2210+ level1 : {
2211+ $ref : '#/definitions/level2' ,
2212+ dependencies : {
2213+ dep1 : {
2214+ allOf : [
2215+ {
2216+ type : 'object' ,
2217+ properties : {
2218+ nested1 : { type : 'string' } ,
2219+ } ,
2220+ } ,
2221+ ] ,
2222+ } ,
2223+ } ,
2224+ } ,
2225+ level2 : {
2226+ type : 'object' ,
2227+ properties : {
2228+ base : { type : 'string' } ,
2229+ } ,
2230+ allOf : [
2231+ {
2232+ type : 'object' ,
2233+ properties : {
2234+ additional : { type : 'number' } ,
2235+ } ,
2236+ } ,
2237+ ] ,
2238+ } ,
2239+ } ,
2240+ } ;
2241+ const formData = { dep1 : 'value' } ;
2242+ const customMergeAllOf = jest . fn ( ) . mockImplementation ( ( schema ) => {
2243+ const allProperties : any = { } ;
2244+ if ( schema . properties ) {
2245+ Object . assign ( allProperties , schema . properties ) ;
2246+ }
2247+ if ( schema . allOf ) {
2248+ schema . allOf . forEach ( ( subSchema : any ) => {
2249+ if ( subSchema . properties ) {
2250+ Object . assign ( allProperties , subSchema . properties ) ;
2251+ }
2252+ } ) ;
2253+ }
2254+ return {
2255+ ...schema ,
2256+ properties : allProperties ,
2257+ allOf : undefined ,
2258+ } ;
2259+ } ) ;
2260+ const result = retrieveSchema ( testValidator , schema , rootSchema , formData , customMergeAllOf ) ;
2261+ // Should be called for both allOf blocks (level2 and dependency)
2262+ expect ( customMergeAllOf ) . toHaveBeenCalledTimes ( 3 ) ;
2263+ expect ( result ) . toEqual ( {
2264+ type : 'object' ,
2265+ properties : {
2266+ base : { type : 'string' } ,
2267+ additional : { type : 'number' } ,
2268+ } ,
2269+ allOf : undefined ,
2270+ } ) ;
2271+ } ) ;
2272+ } ) ;
19292273 } ) ;
19302274}
0 commit comments