Skip to content

Tests: Account for extra focus/blur listeners in jQuery >=3.4 #1930

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 23, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions tests/lib/qunit-assert-domequal.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,28 @@ function getElementStyles( elem ) {
return styles;
}

// Returns 0 if v1 == v2, -1 if v1 < v2, 1 if v1 > v2
function compareVersions( v1, v2 ) {
var i,
rVersionParts = /^(\d+)\.(\d+)\.(\d+)/,
v1p = rVersionParts.exec( v1 ) || [ ],
v2p = rVersionParts.exec( v2 ) || [ ];

for ( i = 1; i <= 3; i++ ) {
if ( +v1p[ i ] > +v2p[ i ] ) {
return 1;
}
if ( +v1p[ i ] < +v2p[ i ] ) {
return -1;
}
}
return 0;
}

function jQueryVersionSince( version ) {
return compareVersions( $.fn.jquery, version ) >= 0;
}

function extract( selector, message ) {
var elem = $( selector );
if ( !elem.length ) {
Expand All @@ -113,6 +135,54 @@ function extract( selector, message ) {
} );
result.style = getElementStyles( elem[ 0 ] );
result.events = $._data( elem[ 0 ], "events" );

// jQuery >=3.4.0 uses a special focus/blur handler pair
// needed to fix various issues with checkboxes/radio buttons
// as well as being able to pass data in focus triggers.
// However, this leaves dummy focus & blur events if any of these
// events were ever listened to at a particular element. There's not
// a lot UI can do to fix this so just skip these handlers for
// data comparisons in tests.
// See https://github.com/jquery/jquery/issues/4496
if ( result.events && jQueryVersionSince( "3.4.0" ) ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we actually need to restrict this code to jQuery >= 3.4.0? What would happen without the check?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought since this excludes some things from the compared objects, in older jQueries where there are no additional listeners we could perform a full check. There's always a risk that the workaround will not account for some real differences and by restricting it to jQuery >=3.4.0 we'd see a test error in older jQuery versions in such a case.

UI is currently tested with Core >=1.8.

var i, eventDataList, eventData;
$.each( [ "focus", "blur" ], function( index, eventType ) {
if ( !result.events[ eventType ] ) {
return;
}

// Only the special internal handlers
// have the namespace field set to boolean `false`;
// filter them out.
result.events[ eventType ] = result.events[ eventType ].filter( function( eventData ) {
return eventData.namespace !== false;
} );

eventDataList = result.events[ eventType ];
for ( i = eventDataList.length - 1; i > -1; i-- ) {
eventData = eventDataList[ i ];

// Only these special jQuery internal handlers
// have the `namespace` field set to `false`;
// all other events use a string value, possibly
// an empty string if no namespace was set.
if ( eventData.namespace === false ) {
eventDataList.splice( i, 1 );
}
}

// Remove empty eventData collections to follow jQuery behavior.
if ( !eventDataList.length ) {
delete result.events[ eventType ];
}
} );

// Simulate empty events collections removal to follow jQuery behavior.
if ( !Object.keys( result.events ).length ) {
result.events = undefined;
}
}

result.data = $.extend( {}, elem.data() );
delete result.data[ $.expando ];
children = elem.children();
Expand Down