PhantomJs Trigger Tests Failing After CanJs Upgrade

After upgrading to canjs 2.3.22 we’ve had several of our phantomjs tests start to fail. Some I’ve been able to correct. However, almost all our trigger tests now fail with eventname undefined errors. The error can be traced back to the /can/map/map/ module. In the code:

shortName: 'Map',
        _bubbleRule: function (eventName) {
            return eventName === 'change' || eventName.indexOf('.') >= 0 ? ['change'] : [];
        },
        bind: can.bindAndSetup,
        unbind: can.unbindAndTeardown,
        id: 'id',

The error is the in the _bubbleRule function.

Here is an example of our code and the test:

Code:

define(["ve3/base/baseClasses", "./models"], function(Base, Models) {
  return {
    // Controller to warn user that a body location was clicked on, but no diagnosis was selected.
    WarnBodyLocationWithoutDiagnosisController: Base.BaseController.extend({
      "{centralEventHub} Ve3_onWarnBodyLocationWithoutDiagnosis": function(centralEventHub) {
        can.trigger(centralEventHub, "Ve3_onOpenAlertDialog",
          {title:"Warning", message:"Please select an impression before selecting a body location."});
      }
    }),
...

Test:

define(["ve3/base/centralEventHub", "ve3/bodyLocation/controllers"],
  function(CentralEventHub, Controllers) {
    describe("bodyLocation/controllers-tests", function() {
      var centralEventHub = null;
      var receiveEvent = null;
      var params = null;
      var controller = null;
  
      beforeEach(function() {
        centralEventHub = new CentralEventHub();
        params = {centralEventHub:centralEventHub};

        if (_.isFunction(top.setVe3CentralEventHubOnVe2)) {
          top.setVe3CentralEventHubOnVe2(centralEventHub);
        }
      });
  
      afterEach(function() {
        if (controller) {
          controller.destroy();
        }
        centralEventHub.unbind();
        centralEventHub = null;
      });
  
      describe("WarnBodyLocationWithoutDiagnosisController", function() {
        it("triggers an alert", function(done) {
          controller = new Controllers.WarnBodyLocationWithoutDiagnosisController(params);
          centralEventHub.bind("Ve3_onOpenAlertDialog", function() { done(); });
          can.trigger(centralEventHub, "Ve3_onWarnBodyLocationWithoutDiagnosis");
        });
      });
      ...

I’m not sure if this is an issue with our code or Canjs. I find it unsettling that almost all our test broke with a minor revision in Canjs (2.0.7 -> 2.3.22). Please realize, I’m not a canjs expert. I was just given the task upgrading our javascript libraries.

I am able to fix this issue, but only by modifying the Canjs code (which I would rather not do – unless this is a bug).

My fix:

_bubbleRule: function (eventName) {
        	if (eventName === undefined) {
        		return [];
        	}
            return eventName === 'change' || eventName.indexOf('.') >= 0 ? ['change'] : [];
        }

Thank you for any help you can provide. Sorry for any formatting issues.

@frankh214 Thanks for reporting. Can you create an issue on github? We’ll fix this in the next release.

I’m interested to see how eventName could possibly be undefined. It’s probably a problem elsewhere, but we should be able to accept strange circumstances.

All of your tests broke? I find that unsettling too. Are they all fixed by this one change? We test 2.3 against 2.0.07’s tests as part of our automated build. So unless the app is using CanJS in unexpected ways, everything should work.

Thanks for the quick reply. I’ll post the issue in github.

No, this change didn’t fix all of our test, just a good many. There are a few other issues as well. I’ve been trying to fix them before posting questions here. I’ve been forced to learn canjs as I go. :slight_smile: So, I’ve only been posting when I get really stuck.

The one that I’m having difficulty with right now is when can.compute is used inside a can.Model.extend and the “this” keyword is used inside the can.compute. For some reason, the “this”, which originally pointed to the model, does not any longer.

Here is an example:

define(["ve3/base/ajax", "ve3/base/util"], function(Ajax, Util) {
  var models = {
    VisitBodyLocationModel: can.Model.extend({
      // static properties
      destroy: function() {
        // Don't issue DELETE request when model instance is destroyed.
        return Util.deferredNoop();
      }
    }, {
      init: function() {
        this.relabelAccordingToPathologyLetter();
        this.bind("pathologyLetter", this.relabelAccordingToPathologyLetter);
      },
      bodyLocationLabel: can.compute(function() {
    	  return this.attr("examDetailDescription") || this.attr("detailedDescription");
      }),
...

In “bodyLocationLabel”, the “this” becomes undefined when the test is called.

Fortunately, several places where this was done, the can.compute wasn’t actually necessary and removing it fixes the issue.