jasmine-jquery icon indicating copy to clipboard operation
jasmine-jquery copied to clipboard

toHandle doesn't support delegated .on() syntax

Open nzifnab opened this issue 11 years ago • 6 comments

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.

nzifnab avatar Sep 09 '13 02:09 nzifnab

:+1:

bradgreens avatar Oct 15 '13 21:10 bradgreens

is this issue being considered?

agreco avatar Nov 19 '13 13:11 agreco

👍

isaachvazquez avatar May 02 '16 16:05 isaachvazquez

👍 What's the status on this one?

erlandsona avatar Jul 11 '16 21:07 erlandsona

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)
}

Jefferson-Faseler avatar Dec 20 '17 19:12 Jefferson-Faseler

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.

Jefferson-Faseler avatar Dec 20 '17 19:12 Jefferson-Faseler