ember-qunit-codemod icon indicating copy to clipboard operation
ember-qunit-codemod copied to clipboard

TypeError: helper.compute is not a function

Open Turbo87 opened this issue 8 years ago • 8 comments

    let helper = this.owner.lookup('helper:format-duration');
    // before: let helper = this.subject();

    let result = helper.compute([convertToMS(59, 'minutes')]);

    assert.equal(result, '59 min');

fails with:

TypeError: helper.compute is not a function

Turbo87 avatar Oct 21 '17 13:10 Turbo87

Was there a custom subject definition before? Can you share the moduleFor setup invocation?

rwjblue avatar Oct 21 '17 14:10 rwjblue

We for sure do not currently support a custom subject definition. If that was it, then this is roughly the same as https://github.com/rwjblue/ember-qunit-codemod/issues/12.

rwjblue avatar Oct 21 '17 14:10 rwjblue

moduleFor('helper:format-duration', 'Unit | Helper | format duration', {
  async beforeEach() {
    await this.container.lookup('service:intl').loadAndSetLocale('en');
  }
});

Turbo87 avatar Oct 21 '17 14:10 Turbo87

I don’t think this is a standard setup here and I’m unsure what exactly is the best path forward. I believe that the default helper tests just import the helpers compute function and test it with “plain qunit”. I presume the setup here is used instead because this is a Ember.Helper.extend() style of helper (as opposed to Ember.Helper.helper(function(){}))?

Ideally, this test would be updated to actually render the helper (e.g. await render(...)), but we should dig a bit more to see why the actual code is failing. It is possible that helper should be added to the array of non-singleton types....

rwjblue avatar Oct 21 '17 14:10 rwjblue

I presume the setup here is used instead because this is a Ember.Helper.extend() style of helper (as opposed to Ember.Helper.helper(function(){}))?

yeah, it's a class-based helper

Turbo87 avatar Oct 21 '17 14:10 Turbo87

for future reference, the correct code would be:

    let helper = this.owner.factoryFor('helper:format-duration').create();
    // before: let helper = this.subject();

    let result = helper.compute([convertToMS(59, 'minutes')]);

    assert.equal(result, '59 min');

tl;dr factoryFor(...).create() instead of lookup(...).

Turbo87 avatar Nov 10 '17 13:11 Turbo87

I made some changes in Ember itself (should be included in 2.17 release next week) to allow the same let helper = this.owner.factoryFor('helper:format-duration').create(); scenario to work in both "class based helper" and "simple helper" cases. See https://github.com/emberjs/ember.js/pull/15848 for a writeup of that...

rwjblue avatar Nov 17 '17 18:11 rwjblue

Based on ^, I am going to update the codemod to transform this.subject() in helper unit tests to the factoryFor(...).create().

rwjblue avatar Nov 17 '17 18:11 rwjblue