Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -152,49 +152,98 @@
});

describe('unnecessary registerDecorators', () => {
it('should provide helpful error for decorator outside of LightningElement, apiVersion=latest', () => {
const actual = `
import { track } from 'lwc'
class Foo {
@track bar = 'baz';
it.for([
{
name: '@api decorator',
code: `
import { api } from 'lwc'
export default class NotComponent {
@api prop
}
`,
},
{
name: '@api decorator with comment between import and usage',
code: `
import { api } from 'lwc'
// the error message should not include the above import
export default class NotComponent {
@api prop
}
`,
},
])(
'should provide helpful error for decorator outside of LightningElement, apiVersion=latest',
({ code }) => {
let error;
try {
transformSync(code, 'foo.js', {
...TRANSFORMATION_OPTIONS,
});
} catch (err) {
error = err;
}
`;
let error;
try {
transformSync(actual, 'foo.js', {
...TRANSFORMATION_OPTIONS,
});
} catch (err) {
error = err;
}

expect(error).not.toBeUndefined();
expect((error as any).message).toContain(
'Decorators like @api, @track, and @wire are only supported in LightningElement classes.'
);
});
expect(error).not.toBeUndefined();
expect((error as any).message).toContain(
'Decorators like @api, @track, and @wire are only supported in LightningElement classes.'
);
}
);

it('should not customize the error message for non-@track/@wire/@api decorators, apiVersion=latest', () => {
const actual = `
const thisIsNotASupportedDecorator = {};
class Foo {
@thisIsNotASupportedDecorator bar = 'baz';
it.for([
{
name: 'non-LWC decorator',
code: `
const thisIsNotASupportedDecorator = {};
class Foo {
@thisIsNotASupportedDecorator bar = 'baz';
}
`,
},
{
name: 'almost-LWC decorator name (@apitrackwire)',
code: `
const apitrackwire = () => {}
export default class NotComponent {
@apitrackwire prop
}
`,
},
{
name: 'decorator from non-lwc import',
code: `import { eschatology } from 'vermont'
export default class Bananaphone {
@eschatology prewire
}`,
},
{
name: 'generic decorator',
code: `
const decorator = () => {}
export default class NotComponent {
@decorator prop
}
`,
},
])(
'should not customize the error message for non-@track/@wire/@api decorators, apiVersion=latest',
({ code }) => {
let error;
try {
transformSync(code, 'foo.js', {
...TRANSFORMATION_OPTIONS,
});
} catch (err) {
error = err;
}
`;
let error;
try {
transformSync(actual, 'foo.js', {
...TRANSFORMATION_OPTIONS,
});
} catch (err) {
error = err;
}

expect(error).not.toBeUndefined();
expect((error as any).message).not.toContain(
'Decorators like @api, @track, and @wire are only supported in LightningElement classes.'
);
});
expect(error).not.toBeUndefined();
expect((error as any).message).not.toContain(

Check failure on line 242 in packages/@lwc/compiler/src/transformers/__tests__/transform-javascript.spec.ts

View workflow job for this annotation

GitHub Actions / run-unit-tests

src/transformers/__tests__/transform-javascript.spec.ts > unnecessary registerDecorators > should not customize the error message for non-@track/@wire/@api decorators, apiVersion=latest

AssertionError: expected 'SyntaxError: LWC1198: Decorators like…' not to contain 'Decorators like @api, @track, and @wi…' - Expected + Received - Decorators like @api, @track, and @wire are only supported in LightningElement classes. + SyntaxError: LWC1198: Decorators like @api, @track, and @wire are only supported in LightningElement classes. /home/runner/work/lwc/lwc/foo.js: Decorators are not enabled. + If you are using ["@babel/plugin-proposal-decorators", { "version": "legacy" }], make sure it comes *before* "@babel/plugin-transform-class-properties" and enable loose mode, like so: + ["@babel/plugin-proposal-decorators", { "version": "legacy" }] + ["@babel/plugin-transform-class-properties", { "loose": true }] + 1 | + 2 | const apitrackwire = () => {} + > 3 | export default class NotComponent { + | ^ + 4 | @apitrackwire prop + 5 | } + 6 | ❯ src/transformers/__tests__/transform-javascript.spec.ts:242:48
'Decorators like @api, @track, and @wire are only supported in LightningElement classes.'
);
}
);

it('should allow decorator outside of LightningElement, apiVersion=59', () => {
const actual = `
Expand Down
3 changes: 2 additions & 1 deletion packages/@lwc/compiler/src/transformers/javascript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ export default function scriptTransform(
if (
(e as any).code === 'BABEL_TRANSFORM_ERROR' &&
(e as any).message?.includes('Decorators are not enabled.') &&
/\b(track|api|wire)\b/.test((e as any).message) // sniff for @track/@api/@wire
// eslint-disable-next-line no-control-regex
/(?:\b|\x1b\S*?)(api|wire|track)\b/.test((e as any).message) // sniff for track/api/wire
) {
transformerError = TransformerErrors.JS_TRANSFORMER_DECORATOR_ERROR;
}
Expand Down
Loading