Skip to content

Commit

Permalink
Merge pull request #75 from ony3000/special-tagged-template
Browse files Browse the repository at this point in the history
Excludes tagged templates starting with `css` from line wrapping
  • Loading branch information
ony3000 authored Sep 22, 2024
2 parents fc7dcb8 + 1d4091a commit f9335f3
Show file tree
Hide file tree
Showing 101 changed files with 4,068 additions and 2 deletions.
50 changes: 50 additions & 0 deletions src/packages/core-parts/finder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,31 @@ export function findTargetClassNameNodes(ast: any, options: ResolvedOptions): Cl
case 'TaggedTemplateExpression': {
nonCommentNodes.push(currentASTNode);

if (
isTypeof(
node,
z.object({
tag: z.object({
type: z.literal('Identifier'),
name: z.string(),
range: z.custom<NodeRange>((value) =>
isTypeof(value, z.tuple([z.number(), z.number()])),
),
}),
}),
) &&
node.tag.name === 'css'
) {
const [tagRangeStart, tagRangeEnd] = node.tag.range;

// Note: In fact, the tag name is not `prettierIgnoreNode`, but it is considered a kind of ignore comment to ignore the template literal that immediately follows it.
prettierIgnoreNodes.push({
type: node.tag.type,
range: [tagRangeStart, tagRangeEnd - 1],
});
break;
}

if (
(isTypeof(
node,
Expand Down Expand Up @@ -2610,6 +2635,31 @@ export function findTargetClassNameNodesForSvelte(
case 'TaggedTemplateExpression': {
nonCommentNodes.push(currentASTNode);

if (
isTypeof(
node,
z.object({
tag: z.object({
type: z.literal('Identifier'),
name: z.string(),
start: z.number(),
end: z.number(),
}),
}),
) &&
node.tag.name === 'css'
) {
const tagRangeStart = node.tag.start;
const tagRangeEnd = node.tag.end;

// Note: In fact, the tag name is not `prettierIgnoreNode`, but it is considered a kind of ignore comment to ignore the template literal that immediately follows it.
prettierIgnoreNodes.push({
type: node.tag.type,
range: [tagRangeStart, tagRangeEnd - 1],
});
break;
}

if (
(isTypeof(
node,
Expand Down
34 changes: 33 additions & 1 deletion tests/v2-test/adaptor.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Plugin } from 'prettier';
import { format } from 'prettier';
import type { Fixture } from 'test-settings';
import { describe, expect, test } from 'vitest';
import { describe, expect, onTestFailed, test } from 'vitest';

// eslint-disable-next-line import/no-extraneous-dependencies
import * as thisPlugin from '@/packages/v2-plugin';
Expand Down Expand Up @@ -30,3 +30,35 @@ export function testEach(
});
});
}

export function testSnapshotEach(
fixtures: Omit<Fixture, 'output'>[],
options: PrettierBaseOptions & { plugins: (string | Plugin)[] },
) {
describe.each(fixtures)('$name', ({ input, options: fixtureOptions }) => {
const fixedOptions = {
...options,
...(fixtureOptions ?? {}),
};
const formattedText = format(input, fixedOptions);
let skipSecondTest = false;

test('expectation', () => {
onTestFailed(() => {
skipSecondTest = true;
});

expect(formattedText).toMatchSnapshot();
});

test('consistency', ({ skip }) => {
if (skipSecondTest) {
skip();
}

const doubleFormattedText = format(formattedText, fixedOptions);

expect(doubleFormattedText).toBe(formattedText);
});
});
}
51 changes: 51 additions & 0 deletions tests/v2-test/angular/issue-73/__snapshots__/absolute.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`'(1) Tagged templates are not supported by default.' > expectation 1`] = `
"<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = tw\`lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque\`;
</script>
"
`;

exports[`'(2) Tagged templates are supported by adding tag function names to the \`customFunctions\` option.' > expectation 1`] = `
"<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = tw\`lorem ipsum dolor sit amet consectetur
adipiscing elit proin ex massa hendrerit eu posuere eu
volutpat id neque pellentesque\`;
</script>
"
`;

exports[`'(3) If a tagged template is written as an argument for a function that supports line wrapping, it will appear to be supported even if the \`customFunctions\` option does not include the tagged function name, but in fact it is supported as a template literal.' > expectation 1`] = `
"<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = classNames(
tw\`lorem ipsum dolor sit amet consectetur adipiscing
elit proin ex massa hendrerit eu posuere eu volutpat id
neque pellentesque\`,
);
</script>
"
`;

exports[`'(4) If the tag function name is \`css\`, the tagged template is considered special and is not supported even if it is written as an argument for a function that supports line wrapping.' > expectation 1`] = `
"<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = classNames(
css\`lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque\`,
);
</script>
"
`;

exports[`'(5) If the tag function name is \`css\`, the tagged template is considered special and is not supported even if you add the tag function name to the \`customFunctions\` option.' > expectation 1`] = `
"<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = classNames(
css\`lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque\`,
);
</script>
"
`;
51 changes: 51 additions & 0 deletions tests/v2-test/angular/issue-73/__snapshots__/ideal.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`'(1) Tagged templates are not supported by default.' > expectation 1`] = `
"<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = tw\`lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque\`;
</script>
"
`;

exports[`'(2) Tagged templates are supported by adding tag function names to the \`customFunctions\` option.' > expectation 1`] = `
"<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = tw\`lorem ipsum dolor sit amet consectetur
adipiscing elit proin ex massa hendrerit eu posuere eu
volutpat id neque pellentesque\`;
</script>
"
`;

exports[`'(3) If a tagged template is written as an argument for a function that supports line wrapping, it will appear to be supported even if the \`customFunctions\` option does not include the tagged function name, but in fact it is supported as a template literal.' > expectation 1`] = `
"<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = classNames(
tw\`lorem ipsum dolor sit amet consectetur adipiscing
elit proin ex massa hendrerit eu posuere eu volutpat id
neque pellentesque\`,
);
</script>
"
`;

exports[`'(4) If the tag function name is \`css\`, the tagged template is considered special and is not supported even if it is written as an argument for a function that supports line wrapping.' > expectation 1`] = `
"<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = classNames(
css\`lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque\`,
);
</script>
"
`;

exports[`'(5) If the tag function name is \`css\`, the tagged template is considered special and is not supported even if you add the tag function name to the \`customFunctions\` option.' > expectation 1`] = `
"<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = classNames(
css\`lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque\`,
);
</script>
"
`;
51 changes: 51 additions & 0 deletions tests/v2-test/angular/issue-73/__snapshots__/relative.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`'(1) Tagged templates are not supported by default.' > expectation 1`] = `
"<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = tw\`lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque\`;
</script>
"
`;

exports[`'(2) Tagged templates are supported by adding tag function names to the \`customFunctions\` option.' > expectation 1`] = `
"<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = tw\`lorem ipsum dolor sit amet consectetur adipiscing elit proin
ex massa hendrerit eu posuere eu volutpat id neque
pellentesque\`;
</script>
"
`;

exports[`'(3) If a tagged template is written as an argument for a function that supports line wrapping, it will appear to be supported even if the \`customFunctions\` option does not include the tagged function name, but in fact it is supported as a template literal.' > expectation 1`] = `
"<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = classNames(
tw\`lorem ipsum dolor sit amet consectetur adipiscing elit proin
ex massa hendrerit eu posuere eu volutpat id neque
pellentesque\`,
);
</script>
"
`;

exports[`'(4) If the tag function name is \`css\`, the tagged template is considered special and is not supported even if it is written as an argument for a function that supports line wrapping.' > expectation 1`] = `
"<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = classNames(
css\`lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque\`,
);
</script>
"
`;

exports[`'(5) If the tag function name is \`css\`, the tagged template is considered special and is not supported even if you add the tag function name to the \`customFunctions\` option.' > expectation 1`] = `
"<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = classNames(
css\`lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque\`,
);
</script>
"
`;
14 changes: 14 additions & 0 deletions tests/v2-test/angular/issue-73/absolute.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { baseOptions } from 'test-settings';

import { thisPlugin, testSnapshotEach } from '../../adaptor';
import { fixtures } from './fixtures';

const options = {
...baseOptions,
plugins: [thisPlugin],
parser: 'angular',
printWidth: 60,
endingPosition: 'absolute',
};

testSnapshotEach(fixtures, options);
55 changes: 55 additions & 0 deletions tests/v2-test/angular/issue-73/fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import type { Fixture } from 'test-settings';

export const fixtures: Omit<Fixture, 'output'>[] = [
{
name: '(1) Tagged templates are not supported by default.',
input: `
<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = tw\`lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque\`;
</script>
`,
},
{
name: '(2) Tagged templates are supported by adding tag function names to the `customFunctions` option.',
input: `
<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = tw\`lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque\`;
</script>
`,
options: {
customFunctions: ['tw'],
},
},
{
name: '(3) If a tagged template is written as an argument for a function that supports line wrapping, it will appear to be supported even if the `customFunctions` option does not include the tagged function name, but in fact it is supported as a template literal.',
input: `
<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = classNames(tw\`lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque\`);
</script>
`,
},
{
name: '(4) If the tag function name is `css`, the tagged template is considered special and is not supported even if it is written as an argument for a function that supports line wrapping.',
input: `
<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = classNames(css\`lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque\`);
</script>
`,
},
{
name: '(5) If the tag function name is `css`, the tagged template is considered special and is not supported even if you add the tag function name to the `customFunctions` option.',
input: `
<!-- ------------------------------------------------------| printWidth=60 -->
<script setup lang="ts">
const classes = classNames(css\`lorem ipsum dolor sit amet consectetur adipiscing elit proin ex massa hendrerit eu posuere eu volutpat id neque pellentesque\`);
</script>
`,
options: {
customFunctions: ['css'],
},
},
];
14 changes: 14 additions & 0 deletions tests/v2-test/angular/issue-73/ideal.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { baseOptions } from 'test-settings';

import { thisPlugin, testSnapshotEach } from '../../adaptor';
import { fixtures } from './fixtures';

const options = {
...baseOptions,
plugins: [thisPlugin],
parser: 'angular',
printWidth: 60,
endingPosition: 'absolute-with-indent',
};

testSnapshotEach(fixtures, options);
14 changes: 14 additions & 0 deletions tests/v2-test/angular/issue-73/relative.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { baseOptions } from 'test-settings';

import { thisPlugin, testSnapshotEach } from '../../adaptor';
import { fixtures } from './fixtures';

const options = {
...baseOptions,
plugins: [thisPlugin],
parser: 'angular',
printWidth: 60,
endingPosition: 'relative',
};

testSnapshotEach(fixtures, options);
Loading

0 comments on commit f9335f3

Please sign in to comment.