Skip to content
Merged
Changes from 1 commit
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
Next Next commit
Tests: Account for extra focus/blur listeners in jQuery >=3.4
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 we now just skip these handlers for
data comparisons in tests.

Ref jquery/jquery#4496
  • Loading branch information
mgol committed Jun 24, 2020
commit e699e44ca1864c344e6b7d70853c8a5019662d75
68 changes: 68 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,52 @@ 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
Copy Markdown
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
Copy Markdown
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;
}

// We're going to do a shallow copy of the event list to
// avoid mutating internal jQuery structures when removing
// extraneous focus/blur handlers.
result.events[ eventType ] = result.events[ eventType ].slice();
Comment thread
mgol marked this conversation as resolved.
Outdated

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