@@ -3404,4 +3404,119 @@ suite('JSON Parser', () => {
34043404 assert . strictEqual ( res . length , 0 ) ;
34053405 } ) ;
34063406
3407+ test ( 'discriminator optimization with deeply nested self-referencing schema' , function ( ) {
3408+ // Schema representing IExpression type with discriminated unions
3409+ // This tests performance with deep nesting (50-100 levels)
3410+ const schema : JSONSchema = {
3411+ $id : 'https://example.com/expression' ,
3412+ oneOf : [
3413+ { type : 'string' } ,
3414+ { type : 'number' } ,
3415+ { type : 'boolean' } ,
3416+ { type : 'null' } ,
3417+ {
3418+ type : 'array' ,
3419+ prefixItems : [
3420+ { const : 'logical.and' } ,
3421+ { $ref : '#' } ,
3422+ { $ref : '#' }
3423+ ] ,
3424+ items : { $ref : '#' } ,
3425+ minItems : 3
3426+ } ,
3427+ {
3428+ type : 'array' ,
3429+ prefixItems : [
3430+ { const : 'logical.or' } ,
3431+ { $ref : '#' } ,
3432+ { $ref : '#' }
3433+ ] ,
3434+ items : { $ref : '#' } ,
3435+ minItems : 3
3436+ } ,
3437+ {
3438+ type : 'array' ,
3439+ prefixItems : [
3440+ { const : 'logical.not' } ,
3441+ { $ref : '#' }
3442+ ] ,
3443+ minItems : 2 ,
3444+ maxItems : 2
3445+ } ,
3446+ {
3447+ type : 'array' ,
3448+ prefixItems : [
3449+ { const : 'compare.eq' } ,
3450+ { $ref : '#' } ,
3451+ { $ref : '#' }
3452+ ] ,
3453+ minItems : 3 ,
3454+ maxItems : 3
3455+ }
3456+ ]
3457+ } ;
3458+ {
3459+ // Simple expression
3460+ const { textDoc, jsonDoc } = toDocument ( '["logical.and", true, false]' ) ;
3461+ const semanticErrors = validate2 ( jsonDoc , textDoc , schema , SchemaDraft . v2020_12 ) ;
3462+ assert . strictEqual ( semanticErrors ! . length , 0 ) ;
3463+ }
3464+ {
3465+ // Nested expression (5 levels)
3466+ const { textDoc, jsonDoc } = toDocument ( '["logical.or", ["logical.and", true, false], ["logical.not", true]]' ) ;
3467+ const semanticErrors = validate2 ( jsonDoc , textDoc , schema , SchemaDraft . v2020_12 ) ;
3468+ assert . strictEqual ( semanticErrors ! . length , 0 ) ;
3469+ }
3470+ {
3471+ // Build a deeply nested expression (500 levels)
3472+ let deepExpression = 'true' ;
3473+ for ( let i = 0 ; i < 500 ; i ++ ) {
3474+ deepExpression = `["logical.not", ${ deepExpression } ]` ;
3475+ }
3476+ const { textDoc, jsonDoc } = toDocument ( deepExpression ) ;
3477+ const semanticErrors = validate2 ( jsonDoc , textDoc , schema , SchemaDraft . v2020_12 ) ;
3478+ assert . strictEqual ( semanticErrors ! . length , 0 ) ;
3479+ }
3480+ {
3481+ // Build an even deeper nested expression (1000 levels)
3482+ let veryDeepExpression = '42' ;
3483+ for ( let i = 0 ; i < 1000 ; i ++ ) {
3484+ if ( i % 2 === 0 ) {
3485+ veryDeepExpression = `["logical.not", ${ veryDeepExpression } ]` ;
3486+ } else {
3487+ veryDeepExpression = `["logical.and", ${ veryDeepExpression } , false]` ;
3488+ }
3489+ }
3490+ const { textDoc, jsonDoc } = toDocument ( veryDeepExpression ) ;
3491+ const semanticErrors = validate2 ( jsonDoc , textDoc , schema , SchemaDraft . v2020_12 ) ;
3492+ assert . strictEqual ( semanticErrors ! . length , 0 ) ;
3493+ }
3494+ {
3495+ // Invalid - unknown operator (should fail quickly with discriminator optimization)
3496+ const { textDoc, jsonDoc } = toDocument ( '["unknown.operator", true, false]' ) ;
3497+ const semanticErrors = validate2 ( jsonDoc , textDoc , schema , SchemaDraft . v2020_12 ) ;
3498+ assert . ok ( semanticErrors ! . length > 0 ) ;
3499+ }
3500+ {
3501+ // Invalid - wrong number of arguments for logical.not
3502+ const { textDoc, jsonDoc } = toDocument ( '["logical.not", true, false]' ) ;
3503+ const semanticErrors = validate2 ( jsonDoc , textDoc , schema , SchemaDraft . v2020_12 ) ;
3504+ assert . ok ( semanticErrors ! . length > 0 ) ;
3505+ }
3506+ {
3507+ // Invalid - deeply nested with error (wrong array structure)
3508+ let deepInvalid = '42' ;
3509+ for ( let i = 0 ; i < 200 ; i ++ ) {
3510+ deepInvalid = `["logical.not", ${ deepInvalid } ]` ;
3511+ }
3512+ // Invalid: logical.and needs at least 2 arguments after the operator, but we provide wrong structure
3513+ deepInvalid = `["logical.and", ${ deepInvalid } ]` ; // Missing second required argument
3514+
3515+ const { textDoc, jsonDoc } = toDocument ( deepInvalid ) ;
3516+ const semanticErrors = validate2 ( jsonDoc , textDoc , schema , SchemaDraft . v2020_12 ) ;
3517+ // Should detect the validation error (not enough items)
3518+ assert . ok ( semanticErrors ! . length > 0 ) ;
3519+ }
3520+ } ) ;
3521+
34073522} ) ;
0 commit comments