Skip to content

Commit 1a22d62

Browse files
authored
Merge pull request #198 from ember-codemods/mixins
add basic support for mixins on native classes
2 parents b7b9863 + ba7c259 commit 1a22d62

File tree

3 files changed

+107
-1
lines changed

3 files changed

+107
-1
lines changed

lib/__tests__/__snapshots__/transform.js.snap

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,36 @@ foo
311311
=========="
312312
`;
313313
314+
exports[`native components basic mixins 1`] = `
315+
"==========
316+
317+
import Component from '@ember/component';
318+
import SuperMixin from 'some-place';
319+
320+
export default class FooComponent extends Component.extends(SuperMixin) {
321+
}
322+
323+
~~~~~~~~~~
324+
foo
325+
~~~~~~~~~~
326+
=> tagName: div
327+
~~~~~~~~~~
328+
329+
import { tagName } from \\"@ember-decorators/component\\";
330+
import Component from '@ember/component';
331+
import SuperMixin from 'some-place';
332+
333+
@tagName(\\"\\")
334+
export default class FooComponent extends Component.extends(SuperMixin) {
335+
}
336+
337+
~~~~~~~~~~
338+
<div ...attributes>
339+
foo
340+
</div>
341+
=========="
342+
`;
343+
314344
exports[`native components handles \`@attribute\` and \`@attributeBindings\` correctly 1`] = `
315345
"==========
316346
@@ -744,3 +774,35 @@ foo
744774
</span>
745775
=========="
746776
`;
777+
778+
exports[`native components replaces existing \`tagName\` on a mixin class 1`] = `
779+
"==========
780+
781+
import Component from '@ember/component';
782+
import { tagName } from '@ember-decorators/component';
783+
import SomeMixin from 'somewhere';
784+
785+
@tagName('span')
786+
export default class FooComponent extends Component.extends(SomeMixin) {
787+
}
788+
789+
~~~~~~~~~~
790+
foo
791+
~~~~~~~~~~
792+
=> tagName: span
793+
~~~~~~~~~~
794+
795+
import Component from '@ember/component';
796+
import { tagName } from '@ember-decorators/component';
797+
import SomeMixin from 'somewhere';
798+
799+
@tagName(\\"\\")
800+
export default class FooComponent extends Component.extends(SomeMixin) {
801+
}
802+
803+
~~~~~~~~~~
804+
<span ...attributes>
805+
foo
806+
</span>
807+
=========="
808+
`;

lib/__tests__/transform.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,20 @@ describe('native components', () => {
304304
expect(generateSnapshot(source, template)).toMatchSnapshot();
305305
});
306306

307+
test('basic mixins', () => {
308+
let source = `
309+
import Component from '@ember/component';
310+
import SuperMixin from 'some-place';
311+
312+
export default class FooComponent extends Component.extends(SuperMixin) {
313+
}
314+
`;
315+
316+
let template = `foo`;
317+
318+
expect(generateSnapshot(source, template)).toMatchSnapshot();
319+
});
320+
307321
test('replaces existing `tagName`', () => {
308322
let source = `
309323
import Component from '@ember/component';
@@ -319,6 +333,22 @@ describe('native components', () => {
319333
expect(generateSnapshot(source, template)).toMatchSnapshot();
320334
});
321335

336+
test('replaces existing `tagName` on a mixin class', () => {
337+
let source = `
338+
import Component from '@ember/component';
339+
import { tagName } from '@ember-decorators/component';
340+
import SomeMixin from 'somewhere';
341+
342+
@tagName('span')
343+
export default class FooComponent extends Component.extends(SomeMixin) {
344+
}
345+
`;
346+
347+
let template = `foo`;
348+
349+
expect(generateSnapshot(source, template)).toMatchSnapshot();
350+
});
351+
322352
test('handles `elementId` correctly', () => {
323353
let source = `
324354
import Component from '@ember/component';

lib/transform.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,22 @@ function checkComponentType(root) {
5757
},
5858
},
5959
});
60+
61+
if (classExport.length === 0) {
62+
// find `export default class FooComponent extends Component.extends(SomeMixin) {}` AST node
63+
classExport = root.find(j.ExportDefaultDeclaration, {
64+
declaration: {
65+
type: 'ClassDeclaration',
66+
superClass: {
67+
type: 'CallExpression',
68+
},
69+
},
70+
});
71+
}
72+
6073
if (classExport.length === 1) {
61-
let className = classExport.get().node.declaration.superClass.name;
74+
const superClass = classExport.get().node.declaration.superClass;
75+
let className = superClass.name || superClass.callee.object.name;
6276
if (
6377
root.find(j.ImportDeclaration, node => {
6478
return (

0 commit comments

Comments
 (0)