@@ -3277,48 +3277,212 @@ t.test('should propagate the new override set to the target node', t => {
32773277 t . end ( )
32783278} )
32793279
3280- t . test ( 'should find inconsistency between the edge\'s override set and the target\'s override set' , t => {
3281- const tree = new Node ( {
3282- loadOverrides : true ,
3283- path : '/root' ,
3284- pkg : {
3285- name : 'root' ,
3286- version : '1.0.0' ,
3287- dependencies : {
3288- mockDep : '1.x' ,
3280+ t . test ( 'override conflict detection with semantic comparison' , t => {
3281+ t . test ( 'non-conflicting different override sets should be valid' , t => {
3282+ // Regression test for issue #8688
3283+ // This validates that the improved semantic conflict detection allows
3284+ // structurally different override sets that don't actually conflict.
3285+
3286+ // Create two different override sets (simulating Vaadin's structure)
3287+ // These override different packages, so they don't conflict
3288+ const overridesComponents = new OverrideSet ( {
3289+ overrides : {
3290+ '@vaadin/react-components' : '24.9.2' ,
32893291 } ,
3292+ } )
3293+
3294+ const overridesComponentsPro = new OverrideSet ( {
32903295 overrides : {
3291- mockDep : '2.x ' ,
3296+ '@vaadin/react-components-pro' : '24.9.2 ' ,
32923297 } ,
3293- } ,
3294- children : [ {
3295- name : 'mockDep' ,
3296- version : '2.0.0' ,
3298+ } )
3299+
3300+ const tree = new Node ( {
3301+ loadOverrides : true ,
3302+ path : '/root' ,
32973303 pkg : {
3304+ name : 'root' ,
3305+ version : '1.0.0' ,
32983306 dependencies : {
3299- subDep : '1.0.0' ,
3307+ mockDep : '1.x' ,
3308+ } ,
3309+ overrides : {
3310+ mockDep : '2.x' ,
33003311 } ,
33013312 } ,
33023313 children : [ {
3303- name : 'subDep' ,
3304- version : '1.0.0' ,
3305- pkg : { } ,
3314+ name : 'mockDep' ,
3315+ version : '2.0.0' ,
3316+ pkg : {
3317+ dependencies : {
3318+ subDep : '1.0.0' ,
3319+ } ,
3320+ } ,
3321+ children : [ {
3322+ name : 'subDep' ,
3323+ version : '1.0.0' ,
3324+ pkg : { } ,
3325+ } ] ,
33063326 } ] ,
3307- } ] ,
3327+ } )
3328+
3329+ const edge = tree . edgesOut . get ( 'mockDep' )
3330+
3331+ // Manually set an override to the edge
3332+ edge . overrides = overridesComponents
3333+
3334+ // Override satisfiedBy so it returns true, ensuring the conflict branch is reached
3335+ edge . satisfiedBy = ( ) => true
3336+
3337+ // Set different but non-conflicting override on the target node
3338+ const mockDep = tree . children . get ( 'mockDep' )
3339+ mockDep . overrides = overridesComponentsPro
3340+
3341+ // Force edge to recalculate
3342+ edge . reload ( true )
3343+
3344+ // The edge should be valid despite different override contexts
3345+ // because they don't have conflicting version requirements
3346+ t . equal ( edge . error , null , 'Edge should be valid with non-conflicting override contexts' )
3347+ t . ok ( edge . valid , 'Edge.valid should be true' )
3348+
3349+ t . end ( )
33083350 } )
33093351
3310- // Force edge.override to a conflicting object so that it will differ from
3311- // the computed override coming from the parent's override set.
3312- const conflictingOverride = new OverrideSet ( {
3313- overrides : { mockDep : '1.x' } ,
3352+ t . test ( 'conflicting override sets should be detected as invalid' , t => {
3353+ // This validates that actual conflicts ARE still caught by the semantic detection
3354+
3355+ // Create two override sets with conflicting version requirements for the same package
3356+ const overridesV1 = new OverrideSet ( {
3357+ overrides : {
3358+ lodash : '1.x' ,
3359+ } ,
3360+ } )
3361+
3362+ const overridesV4 = new OverrideSet ( {
3363+ overrides : {
3364+ lodash : '4.x' ,
3365+ } ,
3366+ } )
3367+
3368+ const tree = new Node ( {
3369+ loadOverrides : true ,
3370+ path : '/root' ,
3371+ pkg : {
3372+ name : 'root' ,
3373+ version : '1.0.0' ,
3374+ dependencies : {
3375+ mockDep : '1.x' ,
3376+ } ,
3377+ overrides : {
3378+ mockDep : '2.x' ,
3379+ } ,
3380+ } ,
3381+ children : [ {
3382+ name : 'mockDep' ,
3383+ version : '2.0.0' ,
3384+ pkg : {
3385+ dependencies : {
3386+ lodash : '1.0.0' ,
3387+ } ,
3388+ } ,
3389+ children : [ {
3390+ name : 'lodash' ,
3391+ version : '1.0.0' ,
3392+ pkg : { } ,
3393+ } ] ,
3394+ } ] ,
3395+ } )
3396+
3397+ const edge = tree . edgesOut . get ( 'mockDep' )
3398+ const mockDep = tree . children . get ( 'mockDep' )
3399+
3400+ // Manually set conflicting overrides
3401+ edge . overrides = overridesV1
3402+ mockDep . overrides = overridesV4
3403+
3404+ // Override satisfiedBy so it returns true, ensuring the conflict branch is reached
3405+ edge . satisfiedBy = ( ) => true
3406+
3407+ // Clear the cached error by calling reload(true)
3408+ edge . reload ( true )
3409+
3410+ // Re-set the overrides after reload (since reload may have changed them)
3411+ edge . overrides = overridesV1
3412+ mockDep . overrides = overridesV4
3413+
3414+ // The edge should be INVALID due to conflicting override requirements
3415+ t . equal ( edge . error , 'INVALID' , 'Edge should be invalid with conflicting override versions' )
3416+ t . notOk ( edge . valid , 'Edge.valid should be false' )
3417+
3418+ t . end ( )
33143419 } )
3315- const edge = tree . edgesOut . get ( 'mockDep' )
3316- edge . overrides = conflictingOverride
33173420
3318- // Override satisfiedBy so it returns true, ensuring the conflict branch is reached
3319- edge . satisfiedBy = ( ) => true
3421+ t . test ( 'reference overrides should not cause false positives' , t => {
3422+ // This validates that reference overrides ($syntax) don't trigger false positives
3423+
3424+ const overridesRef1 = new OverrideSet ( {
3425+ overrides : {
3426+ lodash : '$some-reference' ,
3427+ } ,
3428+ } )
33203429
3321- t . equal ( tree . edgesOut . get ( 'mockDep' ) . error , 'INVALID' , 'Edge should be marked INVALID due to conflicting overrides' )
3430+ const overridesRef2 = new OverrideSet ( {
3431+ overrides : {
3432+ lodash : '$another-reference' ,
3433+ } ,
3434+ } )
3435+
3436+ const tree = new Node ( {
3437+ loadOverrides : true ,
3438+ path : '/root' ,
3439+ pkg : {
3440+ name : 'root' ,
3441+ version : '1.0.0' ,
3442+ dependencies : {
3443+ mockDep : '1.x' ,
3444+ } ,
3445+ overrides : {
3446+ mockDep : '2.x' ,
3447+ } ,
3448+ } ,
3449+ children : [ {
3450+ name : 'mockDep' ,
3451+ version : '2.0.0' ,
3452+ pkg : {
3453+ dependencies : {
3454+ lodash : '4.0.0' ,
3455+ } ,
3456+ } ,
3457+ children : [ {
3458+ name : 'lodash' ,
3459+ version : '4.0.0' ,
3460+ pkg : { } ,
3461+ } ] ,
3462+ } ] ,
3463+ } )
3464+
3465+ const edge = tree . edgesOut . get ( 'mockDep' )
3466+
3467+ // Set reference overrides
3468+ edge . overrides = overridesRef1
3469+
3470+ // Override satisfiedBy so it returns true, ensuring the conflict branch is reached
3471+ edge . satisfiedBy = ( ) => true
3472+
3473+ const mockDep = tree . children . get ( 'mockDep' )
3474+ mockDep . overrides = overridesRef2
3475+
3476+ // Force edge to recalculate
3477+ edge . reload ( true )
3478+
3479+ // Reference overrides should not cause conflicts because we can't determine
3480+ // their compatibility at this stage - they might resolve to the same version
3481+ t . equal ( edge . error , null , 'Edge should be valid with reference overrides' )
3482+ t . ok ( edge . valid , 'Edge.valid should be true with reference overrides' )
3483+
3484+ t . end ( )
3485+ } )
33223486
33233487 t . end ( )
33243488} )
0 commit comments