Skip to content

Commit

Permalink
fix: assert correct param types
Browse files Browse the repository at this point in the history
  • Loading branch information
buschtoens committed Apr 15, 2019
1 parent 0299e67 commit 3167d92
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 49 deletions.
26 changes: 16 additions & 10 deletions addon/modifiers/on.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ const assertValidEventOptions =

function setupListener(element, eventName, callback, eventOptions, params) {
if (DEBUG) assertValidEventOptions(eventOptions, eventName);
assert(
`ember-on-modifier: '${eventName}' is not a valid event name. It has to be a string with a minimum length of 1 character.`,
typeof eventName === 'string' && eventName.length > 1
);
assert(
`ember-on-modifier: '${callback}' is not a valid callback. Provide a function.`,
typeof callback === 'function'
);
deprecate(
`ember-on-modifier: Passing additional arguments to be partially applied to the event listener is deprecated in order to comply with the RFC. Use the '{{fn}}' helper instead: https://www.npmjs.com/package/ember-fn-helper`,
!Array.isArray(params) || params.length === 0,
Expand All @@ -41,22 +49,20 @@ function setupListener(element, eventName, callback, eventOptions, params) {
}
);

if (typeof eventName === 'string' && typeof callback === 'function') {
if (Array.isArray(params) && params.length > 0) {
const _callback = callback;
callback = function(...args) {
return _callback.call(this, ...params, ...args);
};
}

addEventListener(element, eventName, callback, eventOptions);
if (Array.isArray(params) && params.length > 0) {
const _callback = callback;
callback = function(...args) {
return _callback.call(this, ...params, ...args);
};
}

addEventListener(element, eventName, callback, eventOptions);

return callback;
}

function destroyListener(element, eventName, callback, eventOptions) {
if (typeof eventName === 'string' && typeof callback === 'function')
if (element && eventName && callback)
removeEventListener(element, eventName, callback, eventOptions);
}

Expand Down
91 changes: 52 additions & 39 deletions tests/integration/modifiers/on-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,58 @@ module('Integration | Modifier | on', function(hooks) {
);
});

(gte('3.0.0') // I have no clue how to catch the error in Ember 2.13
? test
: skip)('it raises an assertion if an invalid event name or callback is passed in', async function(assert) {
const errors = [];
setupOnerror(error => errors.push(error));

await render(hbs`<button {{on "click" 10}}></button>`);
await render(hbs`<button {{on "click"}}></button>`);
await render(hbs`<button {{on "" undefined}}></button>`);
await render(hbs`<button {{on 10 undefined}}></button>`);
await render(hbs`<button {{on}}></button>`);

assert.deepEqual(errors.map(e => e.message), [
"Assertion Failed: ember-on-modifier: '10' is not a valid callback. Provide a function.",
"Assertion Failed: ember-on-modifier: 'undefined' is not a valid callback. Provide a function.",
"Assertion Failed: ember-on-modifier: '' is not a valid event name. It has to be a string with a minimum length of 1 character.",
"Assertion Failed: ember-on-modifier: '10' is not a valid event name. It has to be a string with a minimum length of 1 character.",
"Assertion Failed: ember-on-modifier: 'undefined' is not a valid event name. It has to be a string with a minimum length of 1 character."
]);
});

(gte('3.0.0') // I have no clue how to catch the error in Ember 2.13
? test
: skip)('it recovers after updating to incorrect parameters', async function(assert) {
assert.expect(3);

const errors = [];
setupOnerror(error => errors.push(error));

let n = 0;
this.someMethod = () => n++;

await render(
hbs`<button data-foo="some-thing" {{on "click" this.someMethod}}></button>`
);

await click('button');
assert.strictEqual(n, 1);

run(() => set(this, 'someMethod', undefined));
await settled();

await click('button');
assert.strictEqual(n, 1);

run(() => set(this, 'someMethod', () => n++));
await settled();

await click('button');
assert.strictEqual(n, 2);
});

test('it passes additional parameters though to the listener', async function(assert) {
assert.expect(4);

Expand Down Expand Up @@ -206,43 +258,4 @@ module('Integration | Modifier | on', function(hooks) {
assert.strictEqual(b, 1);
assert.strictEqual(c, 1);
});

test('it does nothing if the callback or event name is `null` or `undefined`', async function(assert) {
assert.expect(0);

this.someMethod = () => {};

await render(hbs`
<button data-foo="some-thing" {{on "click" null}}></button>
<button data-foo="some-thing" {{on "click" undefined}}></button>
<button data-foo="some-thing" {{on null this.someMethod}}></button>
<button data-foo="some-thing" {{on undefined this.someMethod}}></button>
`);
});

test('it does not crash when updating to or from `null` / `undefined`', async function(assert) {
assert.expect(3);

let n = 0;
this.someMethod = () => n++;

await render(
hbs`<button data-foo="some-thing" {{on "click" this.someMethod}}></button>`
);

await click('button');
assert.strictEqual(n, 1);

run(() => set(this, 'someMethod', undefined));
await settled();

await click('button');
assert.strictEqual(n, 1);

run(() => set(this, 'someMethod', () => n++));
await settled();

await click('button');
assert.strictEqual(n, 2);
});
});

0 comments on commit 3167d92

Please sign in to comment.