Skip to content

Commit

Permalink
fix(engine): add instaceof check workaround (#1165)
Browse files Browse the repository at this point in the history
  • Loading branch information
pmdartus authored Apr 10, 2019
1 parent 21160c6 commit 5490be7
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 1 deletion.
12 changes: 11 additions & 1 deletion packages/@lwc/engine/src/framework/invoker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,17 @@ export function invokeComponentConstructor(vm: UninitializedVM, Ctor: ComponentC
*/
try {
// job
new Ctor();
const result = new Ctor();

// Check indirectly if the constructor result is an instance of LightningElement. Using
// the "instanceof" operator would not work here since Locker Service provides its own
// implementation of LightningElement, so we indirectly check if the base constructor is
// invoked by accessing the component on the vm.
if (vmBeingConstructed.component !== result) {
throw new TypeError(
'Invalid component constructor, the class should extend LightningElement.'
);
}
} catch (e) {
error = Object(e);
} finally {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { LightningElement } from 'lwc';
import { createElement } from 'test-utils';

import NotInvokingSuper from 'x/notInvokingSuper';
import NotReturningThis from 'x/notReturningThis';

it('should throw when trying to invoke the constructor manually', () => {
expect(() => {
new LightningElement();
Expand All @@ -26,3 +29,18 @@ it('should have no property enumerable on the component instance', () => {

expect(enumerableProperties).toEqual([]);
});

it("should fail when the constructor doesn't invoke super()", () => {
expect(() => {
createElement('x-not-invoking-super', { is: NotInvokingSuper });
}).toThrowError(ReferenceError);
});

it('should fail when the constructor return an instance of LightningElement', () => {
expect(() => {
createElement('x-not-returning-this', { is: NotReturningThis });
}).toThrowError(
TypeError,
'Invalid component constructor, the class should extend LightningElement.'
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { LightningElement } from 'lwc';

export default class NotInvokingSuper extends LightningElement {
// eslint-disable-next-line constructor-super
constructor() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { LightningElement } from 'lwc';

export default class NotReturningThis extends LightningElement {
constructor() {
super();
return {};
}
}

0 comments on commit 5490be7

Please sign in to comment.