jasmine-jquery
jasmine-jquery copied to clipboard
toHandle doesn't support delegated .on() syntax
As the title suggests, when you bind an event using this syntax:
$('.my-parent-element').on('click', '.child-element', function(e){
// Do cool things
});
This doesn't work:
expect($(".child-element")).toHandle('click')
But this does:
expect($(".my-parent-element")).toHandle('click')
Event though it's not actually clicking that parent element that causes the function to run. I would almost expect some kind of method like
expect($(".child-element")).toHandleFromDelegation('click')
or something. I saw this: https://github.com/velesin/jasmine-jquery/pull/40 but it was written for deprecated delegation syntax and closed quite some time ago. Is there a matcher I can use to work-around this issue and test that the child element has the handler on it? I'm not sure if it's a bug that toHandle
fails on the child selector, but if it is I can produce a test case if needed.
:+1:
is this issue being considered?
👍
👍 What's the status on this one?
I ran into this problem with some code and didn't find a solution so I made a custom matcher that will just recursively travel up the DOM. It's pretty limited to my own use case so it won't receive a handler function option, but this works until the issue is resolved.
beforeEach(function () {
jasmine.addMatchers({
toHandleThroughDelegation: function () {
return {
compare: function (actual, expected) {
var selector = actual.selector
var eventType = expected
var delegatesEvent = findEventHandlerDelegate($(selector).slice(0,1).parent(), selector, eventType)
return {
pass: delegatesEvent === true
}
}
}
}
});
});
function findEventHandlerDelegate(element, selector, eventType) {
var delegatedData, eventTypeHandlers, doesDelegate
var eventHandlers = $._data( $(element)[0], 'events' )
if (eventHandlers) {
eventTypeHandlers = eventHandlers[eventType]
if (eventTypeHandlers) {
delegatedData = eventTypeHandlers.filter(function(handler) {
return handler.selector === selector
})
if (delegatedData[0]) {
doesDelegate = delegatedData[0].selector === selector
}
}
}
if ($(element).is(document) || doesDelegate) {
return doesDelegate
}
return findEventHandlerDelegate($(element).parent(), selector, eventType)
}
Another weird problem we have hit is that anything delegated to document won't be removed between tests. Another issue you may encounter when testing delegated events.