Skip to content
Merged
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
29 changes: 27 additions & 2 deletions packages/core/__tests__/transform/rewrite.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ describe('Transform: rewriteModule', () => {
contents: stripIndent`
import Component, { hbs } from 'special/component';
export default class MyComponent extends Component(<template></template>) {

}
`,
};
Expand All @@ -429,7 +429,7 @@ describe('Transform: rewriteModule', () => {
export default class MyComponent extends Component(({} as typeof import("@glint/environment-ember-template-imports/-private/dsl")).templateExpression(function(__glintRef__, __glintDSL__: typeof import("@glint/environment-ember-template-imports/-private/dsl")) {
__glintRef__; __glintDSL__;
})) {

}"
`);
});
Expand Down Expand Up @@ -822,5 +822,30 @@ describe('Transform: rewriteModule', () => {
|"
`);
});

test('with implicit export default and satisfies', () => {
let customEnv = GlintEnvironment.load(['ember-loose', 'ember-template-imports']);
let script = {
filename: 'test.gts',
contents: stripIndent`
import type { TOC } from '@ember/component/template-only';
<template>HelloWorld!</template> satisfies TOC<{
Blocks: { default: [] }
}>;
`,
};

let transformedModule = rewriteModule(ts, { script }, customEnv);

expect(transformedModule?.errors).toEqual([]);
expect(transformedModule?.transformedContents).toMatchInlineSnapshot(`
"import type { TOC } from '@ember/component/template-only';
export default ({} as typeof import("@glint/environment-ember-template-imports/-private/dsl")).templateExpression(function(__glintRef__, __glintDSL__: typeof import("@glint/environment-ember-template-imports/-private/dsl")) {
__glintRef__; __glintDSL__;
}) satisfies TOC<{
Blocks: { default: [] }
}>;"
`);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,19 @@ type ETITemplateProperty = ts.PropertyDeclaration & {
name: ts.ComputedPropertyName & { expression: ETITemplateLiteral };
};

type ETIDefaultTemplate = ts.ExpressionStatement & {
expression: ETITemplateLiteral;
};
type ETIDefaultTemplate =
| (ts.ExpressionStatement & {
expression: ETITemplateLiteral;
})
| (ts.SatisfiesExpression & {
expression: ETITemplateLiteral;
});

function isETIDefaultTemplate(ts: TSLib, node: ts.Node): node is ETIDefaultTemplate {
return ts.isExpressionStatement(node) && isETITemplateLiteral(ts, node.expression);
return (
(ts.isExpressionStatement(node) || ts.isSatisfiesExpression(node)) &&
isETITemplateLiteral(ts, node.expression)
);
}

function isETITemplateProperty(ts: TSLib, node: ts.Node): node is ETITemplateProperty {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,41 @@ describe('Environment: ETI', () => {
);
});

test('single template with satisfies', () => {
let source = stripIndent`
import type { TOC } from '@ember/component/template-only';
<template>HelloWorld!</template> satisfies TOC<{
Blocks: { default: [] }
}>;
`;

let { meta, sourceFile } = applyTransform(source);
let satisfiesExpression = (sourceFile.statements[2] as ts.ExpressionStatement)
.expression as ts.SatisfiesExpression;
let templateNode = satisfiesExpression.expression;
let start = source.indexOf('<template>');
let contentStart = start + '<template>'.length;
let contentEnd = source.indexOf('</template>');
let end = contentEnd + '</template>'.length;

expect(meta).toEqual(
new Map([
[
templateNode,
{
prepend: 'export default ',
templateLocation: {
start,
contentStart,
contentEnd,
end,
},
},
],
]),
);
});

test('multiple templates', () => {
let source = stripIndent`
<template>
Expand Down Expand Up @@ -187,5 +222,72 @@ describe('Environment: ETI', () => {
]),
);
});

test('multiple templates with satisfies', () => {
let source = stripIndent`
import type { TOC } from '@ember/component/template-only';
<template>
<Foo />
</template> satisfies TOC<{
Blocks: { default: [] }
}>;

class Foo {
<template>Hello</template>
}
`;

let classStart = source.indexOf('class');
let { meta, sourceFile } = applyTransform(source);
let satisfiesExpression = (sourceFile.statements[2] as ts.ExpressionStatement)
.expression as ts.SatisfiesExpression;
let firstTemplate = satisfiesExpression.expression;
let secondTemplate = (
(
(sourceFile.statements[3] as ts.ClassDeclaration)
.members[0] as ts.ClassStaticBlockDeclaration
).body.statements[0] as ts.ExpressionStatement
).expression;

let firstStart = source.indexOf('<template>');
let firstContentStart = firstStart + '<template>'.length;
let firstContentEnd = source.indexOf('</template>');
let firstEnd = firstContentEnd + '</template>'.length;

let secondStart = source.indexOf('<template>', classStart);
let secondContentStart = secondStart + '<template>'.length;
let secondContentEnd = source.indexOf('</template>', classStart);
let secondEnd = secondContentEnd + '</template>'.length;

expect(meta).toEqual(
new Map<ts.Node, GlintEmitMetadata>([
[
firstTemplate,
{
prepend: 'export default ',
templateLocation: {
start: firstStart,
contentStart: firstContentStart,
contentEnd: firstContentEnd,
end: firstEnd,
},
},
],
[
secondTemplate,
{
prepend: 'static { ',
append: ' }',
templateLocation: {
start: secondStart,
contentStart: secondContentStart,
contentEnd: secondContentEnd,
end: secondEnd,
},
},
],
]),
);
});
});
});
Loading