|
| 1 | +import { isRepoDirty } from '../../packages/@tailwindcss-upgrade/src/utils/git' |
1 | 2 | import { candidate, css, html, js, json, test, ts } from '../utils'
|
2 | 3 |
|
3 | 4 | test(
|
@@ -2595,40 +2596,6 @@ test(
|
2595 | 2596 | },
|
2596 | 2597 | )
|
2597 | 2598 |
|
2598 |
| -test( |
2599 |
| - 'requires Tailwind v3 before attempting an upgrade', |
2600 |
| - { |
2601 |
| - fs: { |
2602 |
| - 'package.json': json` |
2603 |
| - { |
2604 |
| - "dependencies": { |
2605 |
| - "tailwindcss": "workspace:^", |
2606 |
| - "@tailwindcss/upgrade": "workspace:^" |
2607 |
| - } |
2608 |
| - } |
2609 |
| - `, |
2610 |
| - 'tailwind.config.ts': js` export default {} `, |
2611 |
| - 'src/index.html': html` |
2612 |
| - <div class="underline"></div> |
2613 |
| - `, |
2614 |
| - 'src/index.css': css` |
2615 |
| - @tailwind base; |
2616 |
| - @tailwind components; |
2617 |
| - @tailwind utilities; |
2618 |
| - `, |
2619 |
| - }, |
2620 |
| - }, |
2621 |
| - async ({ exec, expect }) => { |
2622 |
| - let output = await exec('npx @tailwindcss/upgrade', {}, { ignoreStdErr: true }).catch((e) => |
2623 |
| - e.toString(), |
2624 |
| - ) |
2625 |
| - |
2626 |
| - expect(output).toMatch( |
2627 |
| - /Tailwind CSS v.* found. The migration tool can only be run on v3 projects./, |
2628 |
| - ) |
2629 |
| - }, |
2630 |
| -) |
2631 |
| - |
2632 | 2599 | test(
|
2633 | 2600 | `upgrades opacity namespace values to percentages`,
|
2634 | 2601 | {
|
@@ -2810,6 +2777,191 @@ test(
|
2810 | 2777 | },
|
2811 | 2778 | )
|
2812 | 2779 |
|
| 2780 | +test( |
| 2781 | + 'upgrades are idempotent, and can run on v4 projects', |
| 2782 | + { |
| 2783 | + fs: { |
| 2784 | + 'package.json': json` |
| 2785 | + { |
| 2786 | + "dependencies": { |
| 2787 | + "tailwindcss": "^3", |
| 2788 | + "@tailwindcss/upgrade": "workspace:^" |
| 2789 | + }, |
| 2790 | + "devDependencies": { |
| 2791 | + "@tailwindcss/cli": "workspace:^" |
| 2792 | + } |
| 2793 | + } |
| 2794 | + `, |
| 2795 | + 'tailwind.config.js': js` |
| 2796 | + /** @type {import('tailwindcss').Config} */ |
| 2797 | + module.exports = { |
| 2798 | + content: ['./src/**/*.{html,js}'], |
| 2799 | + } |
| 2800 | + `, |
| 2801 | + 'src/index.html': html` |
| 2802 | + <div class="ring"></div> |
| 2803 | + `, |
| 2804 | + 'src/input.css': css` |
| 2805 | + @tailwind base; |
| 2806 | + @tailwind components; |
| 2807 | + @tailwind utilities; |
| 2808 | +
|
| 2809 | + .foo { |
| 2810 | + @apply !bg-[var(--my-color)] rounded; |
| 2811 | + } |
| 2812 | + `, |
| 2813 | + }, |
| 2814 | + }, |
| 2815 | + async ({ exec, fs, expect }) => { |
| 2816 | + await exec('npx @tailwindcss/upgrade') |
| 2817 | +
|
| 2818 | + let before = await fs.dumpFiles('./src/**/*.{css,html}') |
| 2819 | + expect(before).toMatchInlineSnapshot(` |
| 2820 | + " |
| 2821 | + --- ./src/index.html --- |
| 2822 | + <div class="ring-3"></div> |
| 2823 | +
|
| 2824 | + --- ./src/input.css --- |
| 2825 | + @import 'tailwindcss'; |
| 2826 | +
|
| 2827 | + /* |
| 2828 | + The default border color has changed to \`currentcolor\` in Tailwind CSS v4, |
| 2829 | + so we've added these compatibility styles to make sure everything still |
| 2830 | + looks the same as it did with Tailwind CSS v3. |
| 2831 | +
|
| 2832 | + If we ever want to remove these styles, we need to add an explicit border |
| 2833 | + color utility to any element that depends on these defaults. |
| 2834 | + */ |
| 2835 | + @layer base { |
| 2836 | + *, |
| 2837 | + ::after, |
| 2838 | + ::before, |
| 2839 | + ::backdrop, |
| 2840 | + ::file-selector-button { |
| 2841 | + border-color: var(--color-gray-200, currentcolor); |
| 2842 | + } |
| 2843 | + } |
| 2844 | +
|
| 2845 | + .foo { |
| 2846 | + @apply bg-(--my-color)! rounded-sm; |
| 2847 | + } |
| 2848 | + " |
| 2849 | + `) |
| 2850 | +
|
| 2851 | + // Commit the changes |
| 2852 | + if (isRepoDirty()) { |
| 2853 | + await exec('git add .') |
| 2854 | + await exec('git commit -m "upgrade"') |
| 2855 | + } |
| 2856 | +
|
| 2857 | + // Run the upgrade again |
| 2858 | + let output = await exec('npx @tailwindcss/upgrade') |
| 2859 | + expect(output).toContain('No changes were made to your repository') |
| 2860 | +
|
| 2861 | + let after = await fs.dumpFiles('./src/**/*.{css,html}') |
| 2862 | + expect(after).toMatchInlineSnapshot(` |
| 2863 | + " |
| 2864 | + --- ./src/index.html --- |
| 2865 | + <div class="ring-3"></div> |
| 2866 | +
|
| 2867 | + --- ./src/input.css --- |
| 2868 | + @import 'tailwindcss'; |
| 2869 | +
|
| 2870 | + /* |
| 2871 | + The default border color has changed to \`currentcolor\` in Tailwind CSS v4, |
| 2872 | + so we've added these compatibility styles to make sure everything still |
| 2873 | + looks the same as it did with Tailwind CSS v3. |
| 2874 | +
|
| 2875 | + If we ever want to remove these styles, we need to add an explicit border |
| 2876 | + color utility to any element that depends on these defaults. |
| 2877 | + */ |
| 2878 | + @layer base { |
| 2879 | + *, |
| 2880 | + ::after, |
| 2881 | + ::before, |
| 2882 | + ::backdrop, |
| 2883 | + ::file-selector-button { |
| 2884 | + border-color: var(--color-gray-200, currentcolor); |
| 2885 | + } |
| 2886 | + } |
| 2887 | +
|
| 2888 | + .foo { |
| 2889 | + @apply bg-(--my-color)! rounded-sm; |
| 2890 | + } |
| 2891 | + " |
| 2892 | + `) |
| 2893 | +
|
| 2894 | + // Ensure the file system is in the same state |
| 2895 | + expect(before).toEqual(after) |
| 2896 | + }, |
| 2897 | +) |
| 2898 | +
|
| 2899 | +test( |
| 2900 | + 'upgrades run on v4 projects', |
| 2901 | + { |
| 2902 | + fs: { |
| 2903 | + 'package.json': json` |
| 2904 | + { |
| 2905 | + "dependencies": { |
| 2906 | + "tailwindcss": "^4", |
| 2907 | + "@tailwindcss/upgrade": "workspace:^" |
| 2908 | + }, |
| 2909 | + "devDependencies": { |
| 2910 | + "@tailwindcss/cli": "workspace:^" |
| 2911 | + } |
| 2912 | + } |
| 2913 | + `, |
| 2914 | + 'src/index.html': html` |
| 2915 | + <!-- Migrating 'ring', 'rounded' and 'outline-none' are unsafe in v4 -> v4 migrations --> |
| 2916 | + <div class="ring rounded outline"></div> |
| 2917 | +
|
| 2918 | + <!-- Variant order is also unsafe to change in v4 projects --> |
| 2919 | + <div class="file:hover:flex *:hover:flex"></div> |
| 2920 | + <div class="hover:file:flex hover:*:flex"></div> |
| 2921 | +
|
| 2922 | + <!-- These are safe to migrate: --> |
| 2923 | + <div |
| 2924 | + class="!flex bg-red-500/[var(--my-opacity)] [@media(pointer:fine)]:flex bg-right-bottom object-left-top" |
| 2925 | + ></div> |
| 2926 | + `, |
| 2927 | + 'src/input.css': css` |
| 2928 | + @import 'tailwindcss'; |
| 2929 | +
|
| 2930 | + .foo { |
| 2931 | + @apply !bg-[var(--my-color)]; |
| 2932 | + } |
| 2933 | + `, |
| 2934 | + }, |
| 2935 | + }, |
| 2936 | + async ({ exec, fs, expect }) => { |
| 2937 | + await exec('npx @tailwindcss/upgrade') |
| 2938 | + |
| 2939 | + expect(await fs.dumpFiles('./src/**/*.{css,html}')).toMatchInlineSnapshot(` |
| 2940 | + " |
| 2941 | + --- ./src/index.html --- |
| 2942 | + <!-- Migrating 'ring', 'rounded' and 'outline-none' are unsafe in v4 -> v4 migrations --> |
| 2943 | + <div class="ring rounded outline"></div> |
| 2944 | +
|
| 2945 | + <!-- Variant order is also unsafe to change in v4 projects --> |
| 2946 | + <div class="file:hover:flex *:hover:flex"></div> |
| 2947 | + <div class="hover:file:flex hover:*:flex"></div> |
| 2948 | +
|
| 2949 | + <!-- These are safe to migrate: --> |
| 2950 | + <div |
| 2951 | + class="flex! bg-red-500/(--my-opacity) pointer-fine:flex bg-bottom-right object-top-left" |
| 2952 | + ></div> |
| 2953 | +
|
| 2954 | + --- ./src/input.css --- |
| 2955 | + @import 'tailwindcss'; |
| 2956 | +
|
| 2957 | + .foo { |
| 2958 | + @apply bg-(--my-color)!; |
| 2959 | + } |
| 2960 | + " |
| 2961 | + `) |
| 2962 | + }, |
| 2963 | +) |
| 2964 | + |
2813 | 2965 | function withBOM(text: string): string {
|
2814 | 2966 | return '\uFEFF' + text
|
2815 | 2967 | }
|
0 commit comments