More intelligent transformation of `this.on`.
Opened this issue · 1 comments
Support for transforming this.on
usage landed in #56 (issue with detailed writup in #45).
In order to support this.on
in all of the same capacities as was supported in the older ember-qunit@2 API the transformation added in #56 roughly translates this:
moduleForComponent('foo-bar', 'Integration | Component | FooBar', {
integration: true
});
test('it happens', function(assert) {
assert.expect(1);
this.on('test', () => assert.ok(true));
this.render(hbs`{{test-component test="test"}}`);
});
Into:
module('Integration | Component | FooBar', function(hooks) {
setupRenderingTest(hooks);
hooks.beforeEach(function() {
this.actions = {};
this.send = (actionName, ...args) => this.actions[actionName].apply(this, args);
});
test('it happens', async function(assert) {
assert.expect(1);
this.actions.test = () => assert.ok(true);
await render(hbs`{{test-component test="test"}}`);
});
});
Adding this.send
as a function is how this.on
supports "string actions" passed into components. In that "string action" case the current transpilation is the best it can be, however the vast majority of usages in the wild of this.on
are actually still using the action as a "closure action" like this:
moduleForComponent('foo-bar', 'Integration | Component | FooBar', {
integration: true
});
test('it happens', function(assert) {
assert.expect(1);
this.on('test', () => assert.ok(true));
this.render(hbs`{{test-component test=(action 'test')}}`);
});
In this scenario (when the action is used with (action
) we would prefer the following as the codemod output:
module('Integration | Component | FooBar', function(hooks) {
setupRenderingTest(hooks);
test('it happens', async function(assert) {
assert.expect(1);
this.set('test', () => assert.ok(true));
await render(hbs`{{test-component test=(action test)}}`);
});
});
@bendemboski - Based on our conversation in emberjs/ember-test-helpers#232.
/cc @rondale-sc