Improve css expectations in tests (#5819)

* use String.raw for css escapes

This will allow us to write code like:
```css
.mobile\:font-bold {}
```
Instead of
```css
.mobile\\:font-bold {}
```

Which resembles "real" css way better in our tests.

* use String.raw in integration tests as well
This commit is contained in:
Robin Malfait 2021-10-18 12:08:48 +02:00 committed by GitHub
parent 5809c4d07c
commit f12c0e1fa5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 154 additions and 161 deletions

View File

@ -115,7 +115,7 @@ describe.skip('watcher', () => {
font-weight: 700;
}
@media (min-width: 768px) {
.md\\:font-medium {
.md\:font-medium {
font-weight: 500;
}
}
@ -153,7 +153,7 @@ describe.skip('watcher', () => {
font-weight: bold;
}
@media (min-width: 800px) {
.md\\:font-medium {
.md\:font-medium {
font-weight: 500;
}
}

View File

@ -95,7 +95,7 @@ describe('watcher', () => {
font-weight: 700;
}
@media (min-width: 768px) {
.md\\:font-medium {
.md\:font-medium {
font-weight: 500;
}
}
@ -132,7 +132,7 @@ describe('watcher', () => {
font-weight: bold;
}
@media (min-width: 800px) {
.md\\:font-medium {
.md\:font-medium {
font-weight: 500;
}
}

View File

@ -90,7 +90,7 @@ describe.each([{ TAILWIND_MODE: 'watch' }, { TAILWIND_MODE: undefined }])('watch
font-weight: 700;
}
@media (min-width: 768px) {
.md\\:font-medium {
.md\:font-medium {
font-weight: 500;
}
}
@ -127,7 +127,7 @@ describe.each([{ TAILWIND_MODE: 'watch' }, { TAILWIND_MODE: undefined }])('watch
font-weight: bold;
}
@media (min-width: 800px) {
.md\\:font-medium {
.md\:font-medium {
font-weight: 500;
}
}

View File

@ -1,6 +1,2 @@
// Small helper to allow for css, html and JavaScript highlighting / formatting in most editors.
function syntax(templates) {
return templates.join('')
}
module.exports = { css: syntax, html: syntax, javascript: syntax }
module.exports = { css: String.raw, html: String.raw, javascript: String.raw }

View File

@ -188,7 +188,7 @@ describe('watcher', () => {
font-weight: 700;
}
@media (min-width: 768px) {
.md\\:font-medium {
.md\:font-medium {
font-weight: 500;
}
}
@ -225,7 +225,7 @@ describe('watcher', () => {
font-weight: bold;
}
@media (min-width: 800px) {
.md\\:font-medium {
.md\:font-medium {
font-weight: 500;
}
}

View File

@ -121,7 +121,7 @@ describe('watcher', () => {
font-weight: 700;
}
@media (min-width: 768px) {
.md\\:font-medium {
.md\:font-medium {
font-weight: 500;
}
}
@ -158,7 +158,7 @@ describe('watcher', () => {
font-weight: bold;
}
@media (min-width: 800px) {
.md\\:font-medium {
.md\:font-medium {
font-weight: 500;
}
}

View File

@ -91,7 +91,7 @@ describe.each([{ TAILWIND_MODE: 'watch' }, { TAILWIND_MODE: undefined }])('watch
font-weight: 700;
}
@media (min-width: 768px) {
.md\\:font-medium {
.md\:font-medium {
font-weight: 500;
}
}
@ -129,7 +129,7 @@ describe.each([{ TAILWIND_MODE: 'watch' }, { TAILWIND_MODE: undefined }])('watch
font-weight: bold;
}
@media (min-width: 800px) {
.md\\:font-medium {
.md\:font-medium {
font-weight: 500;
}
}

View File

@ -91,7 +91,7 @@ describe.each([{ TAILWIND_MODE: 'watch' }, { TAILWIND_MODE: undefined }])('watch
font-weight: 700;
}
@media (min-width: 768px) {
.md\\:font-medium {
.md\:font-medium {
font-weight: 500;
}
}
@ -129,7 +129,7 @@ describe.each([{ TAILWIND_MODE: 'watch' }, { TAILWIND_MODE: undefined }])('watch
font-weight: bold;
}
@media (min-width: 800px) {
.md\\:font-medium {
.md\:font-medium {
font-weight: 500;
}
}

View File

@ -30,7 +30,7 @@ test('basic', () => {
opacity: 0;
}
}
.hover\\:animate-ping:hover {
.hover\:animate-ping:hover {
animation: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;
}
@keyframes bounce {
@ -44,7 +44,7 @@ test('basic', () => {
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
}
.group:hover .group-hover\\:animate-bounce {
.group:hover .group-hover\:animate-bounce {
animation: bounce 1s infinite;
}
`)

View File

@ -44,12 +44,12 @@ it('should support arbitrary values for various background utilities', () => {
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
}
.bg-\\[\\#ff0000\\] {
.bg-\[\#ff0000\] {
--tw-bg-opacity: 1;
background-color: rgb(255 0 0 / var(--tw-bg-opacity));
}
.bg-\\[color\\:var\\(--bg-color\\)\\] {
.bg-\[color\:var\(--bg-color\)\] {
background-color: var(--bg-color);
}
@ -57,11 +57,11 @@ it('should support arbitrary values for various background utilities', () => {
background-image: linear-gradient(to right, var(--tw-gradient-stops));
}
.bg-\\[url\\(\\'\\/image-1-0\\.png\\'\\)\\] {
.bg-\[url\(\'\/image-1-0\.png\'\)\] {
background-image: url('/image-1-0.png');
}
.bg-\\[url\\:var\\(--image-url\\)\\] {
.bg-\[url\:var\(--image-url\)\] {
background-image: var(--image-url);
}
`)
@ -86,8 +86,8 @@ it('should handle unknown typehints', () => {
let config = { content: [{ raw: html`<div class="w-[length:12px]"></div>` }] }
return run('@tailwind utilities', config).then((result) => {
return expect(result.css).toMatchFormattedCss(`
.w-\\[length\\:12px\\] {
return expect(result.css).toMatchFormattedCss(css`
.w-\[length\:12px\] {
width: 12px;
}
`)
@ -95,6 +95,13 @@ it('should handle unknown typehints', () => {
})
it('should convert _ to spaces', () => {
// Using custom css function here, because otherwise with String.raw, we run
// into an issue with `\2c ` escapes. If we use `\2c ` then JS complains
// about strict mode. But `\\2c ` is not what it expected.
function css(templates) {
return templates.join('')
}
let config = {
content: [
{
@ -185,13 +192,13 @@ it('should convert _ to spaces', () => {
it('should not convert escaped underscores with spaces', () => {
let config = {
content: [{ raw: html` <div class="content-['snake\\_case']"></div> ` }],
content: [{ raw: `<div class="content-['snake\\_case']"></div>` }],
corePlugins: { preflight: false },
}
return run('@tailwind utilities', config).then((result) => {
return expect(result.css).toMatchFormattedCss(css`
.content-\\[\\'snake\\\\_case\\'\\] {
.content-\[\'snake\\_case\'\] {
content: 'snake_case';
}
`)

View File

@ -7,7 +7,7 @@ test('basic color opacity modifier', async () => {
return run('@tailwind utilities', config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.bg-red-500\\/50 {
.bg-red-500\/50 {
background-color: rgb(239 68 68 / 0.5);
}
`)
@ -28,7 +28,7 @@ test('colors with slashes are matched first', async () => {
return run('@tailwind utilities', config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.bg-red-500\\/50 {
.bg-red-500\/50 {
--tw-bg-opacity: 1;
background-color: rgb(255 0 0 / var(--tw-bg-opacity));
}
@ -43,7 +43,7 @@ test('arbitrary color opacity modifier', async () => {
return run('@tailwind utilities', config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.bg-red-500\\/\\[var\\(--opacity\\)\\] {
.bg-red-500\/\[var\(--opacity\)\] {
background-color: rgb(239 68 68 / var(--opacity));
}
`)
@ -67,11 +67,9 @@ test('arbitrary color with opacity from scale', async () => {
plugins: [],
}
let css = `@tailwind utilities`
return run(css, config).then((result) => {
expect(result.css).toMatchFormattedCss(`
.bg-\\[wheat\\]\\/50 {
return run('@tailwind utilities', config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.bg-\[wheat\]\/50 {
background-color: rgb(245 222 179 / 0.5);
}
`)
@ -85,11 +83,9 @@ test('arbitrary color with arbitrary opacity', async () => {
plugins: [],
}
let css = `@tailwind utilities`
return run(css, config).then((result) => {
expect(result.css).toMatchFormattedCss(`
.bg-\\[\\#bada55\\]\\/\\[0\\.2\\] {
return run('@tailwind utilities', config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.bg-\[\#bada55\]\/\[0\.2\] {
background-color: rgb(186 218 85 / 0.2);
}
`)
@ -103,9 +99,7 @@ test('undefined theme color with opacity from scale', async () => {
plugins: [],
}
let css = `@tailwind utilities`
return run(css, config).then((result) => {
return run('@tailwind utilities', config).then((result) => {
expect(result.css).toMatchFormattedCss(``)
})
})
@ -143,7 +137,7 @@ test('function colors are supported', async () => {
return run('@tailwind utilities', config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.bg-blue\\/50 {
.bg-blue\/50 {
background-color: rgba(var(--colors-blue), 0.5);
}
`)
@ -171,14 +165,14 @@ test('utilities that support any type are supported', async () => {
return run('@tailwind utilities', config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.from-red-500\\/50 {
.from-red-500\/50 {
--tw-gradient-from: rgb(239 68 68 / 0.5);
--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to, rgb(239 68 68 / 0));
}
.fill-red-500\\/25 {
.fill-red-500\/25 {
fill: rgb(239 68 68 / 0.25);
}
.placeholder-red-500\\/75::placeholder {
.placeholder-red-500\/75::placeholder {
color: rgb(239 68 68 / 0.75);
}
`)

View File

@ -326,16 +326,16 @@ test('container can use variants', () => {
return run('@tailwind components', config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
@media (min-width: 1024px) {
.lg\\:hover\\:container:hover {
.lg\:hover\:container:hover {
width: 100%;
}
@media (min-width: 400px) {
.lg\\:hover\\:container:hover {
.lg\:hover\:container:hover {
max-width: 400px;
}
}
@media (min-width: 500px) {
.lg\\:hover\\:container:hover {
.lg\:hover\:container:hover {
max-width: 500px;
}
}

View File

@ -586,7 +586,7 @@ test('plugins can create rules with escaped selectors', () => {
return run('@tailwind utilities', config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.custom-top-1\\/4 {
.custom-top-1\/4 {
top: 25%;
}
`)
@ -866,7 +866,7 @@ test('when important is a selector it scopes all selectors in a rule, even thoug
return run('@tailwind utilities', config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
#app .custom-rotate-90,
#app .custom-rotate-1\\/4 {
#app .custom-rotate-1\/4 {
transform: rotate(90deg);
transform: rotate(90deg);
}
@ -1110,7 +1110,7 @@ test('prefix will prefix all classes in a selector', () => {
return run('@tailwind components', config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.tw-btn-blue .tw-w-1\\/4 > h1.tw-text-xl + a .tw-bar {
.tw-btn-blue .tw-w-1\/4 > h1.tw-text-xl + a .tw-bar {
background-color: blue;
}
`)
@ -1251,11 +1251,11 @@ test('plugins can be created using the `createPlugin` function', () => {
.test-lg {
test-property: 3rem;
}
.hover\\:test-sm:hover {
.hover\:test-sm:hover {
test-property: 1rem;
}
@media (min-width: 400px) {
.sm\\:test-sm {
.sm\:test-sm {
test-property: 1rem;
}
}
@ -1314,11 +1314,11 @@ test('plugins with extra options can be created using the `createPlugin.withOpti
.banana-lg {
test-property: 3rem;
}
.hover\\:banana-sm:hover {
.hover\:banana-sm:hover {
test-property: 1rem;
}
@media (min-width: 400px) {
.sm\\:banana-sm {
.sm\:banana-sm {
test-property: 1rem;
}
}
@ -1356,7 +1356,7 @@ test('plugins should cache correctly', () => {
}
@media (min-width: 400px) {
.sm\\:banana {
.sm\:banana {
position: absolute;
}
}
@ -1368,7 +1368,7 @@ test('plugins should cache correctly', () => {
}
@media (min-width: 400px) {
.sm\\:apple {
.sm\:apple {
position: absolute;
}
}
@ -1431,11 +1431,11 @@ test('plugins created using `createPlugin.withOptions` do not need to be invoked
.banana-lg {
test-property: 3rem;
}
.hover\\:banana-sm:hover {
.hover\:banana-sm:hover {
test-property: 1rem;
}
@media (min-width: 400px) {
.sm\\:banana-sm {
.sm\:banana-sm {
test-property: 1rem;
}
}
@ -1486,11 +1486,11 @@ test('the configFunction parameter is optional when using the `createPlugin.with
.banana-lg {
test-property: 3px;
}
.hover\\:banana-sm:hover {
.hover\:banana-sm:hover {
test-property: 1px;
}
@media (min-width: 400px) {
.sm\\:banana-sm {
.sm\:banana-sm {
test-property: 1px;
}
}
@ -1528,7 +1528,7 @@ test('keyframes are not escaped', () => {
}
}
.foo-\\[abc\\] {
.foo-\[abc\] {
animation: abc 1s infinite;
}
@ -1539,7 +1539,7 @@ test('keyframes are not escaped', () => {
}
}
.md\\:foo-\\[def\\] {
.md\:foo-\[def\] {
animation: def 1s infinite;
}
}

View File

@ -11,7 +11,7 @@ test('it uses the values from the custom config file', () => {
return run('@tailwind utilities', config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
@media (min-width: 400px) {
.mobile\\:font-bold {
.mobile\:font-bold {
font-weight: 700;
}
}
@ -32,7 +32,7 @@ test('custom config can be passed as an object', () => {
return run('@tailwind utilities', config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
@media (min-width: 400px) {
.mobile\\:font-bold {
.mobile\:font-bold {
font-weight: 700;
}
}
@ -48,7 +48,7 @@ test('custom config path can be passed using `config` property in an object', ()
return run('@tailwind utilities', config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
@media (min-width: 400px) {
.mobile\\:font-bold {
.mobile\:font-bold {
font-weight: 700;
}
}
@ -71,7 +71,7 @@ test('custom config can be passed under the `config` property', () => {
return run('@tailwind utilities', config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
@media (min-width: 400px) {
.mobile\\:font-bold {
.mobile\:font-bold {
font-weight: 700;
}
}
@ -96,7 +96,7 @@ test('tailwind.config.cjs is picked up by default', () => {
return run('@tailwind utilities').then((result) => {
expect(result.css).toMatchFormattedCss(css`
@media (min-width: 400px) {
.mobile\\:font-bold {
.mobile\:font-bold {
font-weight: 700;
}
}
@ -122,7 +122,7 @@ test('tailwind.config.js is picked up by default', () => {
return run('@tailwind utilities').then((result) => {
expect(result.css).toMatchFormattedCss(css`
@media (min-width: 400px) {
.mobile\\:font-bold {
.mobile\:font-bold {
font-weight: 700;
}
}
@ -148,7 +148,7 @@ test('tailwind.config.cjs is picked up by default when passing an empty object',
return run('@tailwind utilities', {}).then((result) => {
expect(result.css).toMatchFormattedCss(css`
@media (min-width: 400px) {
.mobile\\:font-bold {
.mobile\:font-bold {
font-weight: 700;
}
}
@ -174,7 +174,7 @@ test('tailwind.config.js is picked up by default when passing an empty object',
return run('@tailwind utilities', {}).then((result) => {
expect(result.css).toMatchFormattedCss(css`
@media (min-width: 400px) {
.mobile\\:font-bold {
.mobile\:font-bold {
font-weight: 700;
}
}

View File

@ -15,7 +15,7 @@ it('should be possible to use the darkMode "class" mode', () => {
return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.dark .dark\\:font-bold {
.dark .dark\:font-bold {
font-weight: 700;
}
`)
@ -38,7 +38,7 @@ it('should be possible to use the darkMode "media" mode', () => {
return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
@media (prefers-color-scheme: dark) {
.dark\\:font-bold {
.dark\:font-bold {
font-weight: 700;
}
}
@ -61,7 +61,7 @@ it('should default to the `media` mode when no mode is provided', () => {
return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
@media (prefers-color-scheme: dark) {
.dark\\:font-bold {
.dark\:font-bold {
font-weight: 700;
}
}
@ -85,7 +85,7 @@ it('should default to the `media` mode when mode is set to `false`', () => {
return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
@media (prefers-color-scheme: dark) {
.dark\\:font-bold {
.dark\:font-bold {
font-weight: 700;
}
}

View File

@ -47,7 +47,7 @@ test('experimental universal selector improvements (pseudo hover)', () => {
return run(input, config).then((result) => {
expect(result.css).toMatchCss(css`
.hover\\:shadow {
.hover\:shadow {
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
@ -57,7 +57,7 @@ test('experimental universal selector improvements (pseudo hover)', () => {
resize: both;
}
.hover\\:shadow:hover {
.hover\:shadow:hover {
--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px 0 rgb(0 0 0 / 0.06);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
var(--tw-shadow);
@ -80,7 +80,7 @@ test('experimental universal selector improvements (multiple classes: group)', (
return run(input, config).then((result) => {
expect(result.css).toMatchCss(css`
.group-hover\\:shadow {
.group-hover\:shadow {
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
@ -90,7 +90,7 @@ test('experimental universal selector improvements (multiple classes: group)', (
resize: both;
}
.group:hover .group-hover\\:shadow {
.group:hover .group-hover\:shadow {
--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px 0 rgb(0 0 0 / 0.06);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
var(--tw-shadow);
@ -145,7 +145,7 @@ test('experimental universal selector improvements (hover:divide-y)', () => {
return run(input, config).then((result) => {
expect(result.css).toMatchCss(css`
.hover\\:divide-y > * {
.hover\:divide-y > * {
--tw-border-opacity: 1;
border-color: rgb(229 231 235 / var(--tw-border-opacity));
}
@ -154,7 +154,7 @@ test('experimental universal selector improvements (hover:divide-y)', () => {
resize: both;
}
.hover\\:divide-y:hover > :not([hidden]) ~ :not([hidden]) {
.hover\:divide-y:hover > :not([hidden]) ~ :not([hidden]) {
--tw-divide-y-reverse: 0;
border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
border-bottom-width: calc(1px * var(--tw-divide-y-reverse));

View File

@ -9,7 +9,7 @@ test('PHP arrays', async () => {
return run('@tailwind utilities', config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.max-w-\\[16rem\\] {
.max-w-\[16rem\] {
max-width: 16rem;
}
`)
@ -21,7 +21,7 @@ test('arbitrary values with quotes', async () => {
return run('@tailwind utilities', config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.content-\\[\\'hello\\]\\'\\] {
.content-\[\'hello\]\'\] {
content: 'hello]';
}
`)

View File

@ -40,10 +40,10 @@ test('custom user-land utilities', () => {
.align-banana {
text-align: banana;
}
.hover\\:align-banana:hover {
.hover\:align-banana:hover {
text-align: banana;
}
.focus\\:hover\\:align-chocolate:hover:focus {
.focus\:hover\:align-chocolate:hover:focus {
text-align: chocolate;
}
`)

View File

@ -47,16 +47,16 @@ it('should be possible to matchComponents', () => {
--tw-shadow: 0 0 #0000;
}
.card-\\[\\#0088cc\\] {
.card-\[\#0088cc\] {
color: #0088cc;
}
.card-\\[\\#0088cc\\] .card-header {
.card-\[\#0088cc\] .card-header {
border-top-width: 3px;
border-top-color: #0088cc;
}
.card-\\[\\#0088cc\\] .card-footer {
.card-\[\#0088cc\] .card-footer {
border-bottom-width: 3px;
border-bottom-color: #0088cc;
}
@ -75,16 +75,16 @@ it('should be possible to matchComponents', () => {
var(--tw-shadow);
}
.hover\\:card-\\[\\#f0f\\]:hover {
.hover\:card-\[\#f0f\]:hover {
color: #f0f;
}
.hover\\:card-\\[\\#f0f\\]:hover .card-header {
.hover\:card-\[\#f0f\]:hover .card-header {
border-top-width: 3px;
border-top-color: #f0f;
}
.hover\\:card-\\[\\#f0f\\]:hover .card-footer {
.hover\:card-\[\#f0f\]:hover .card-footer {
border-bottom-width: 3px;
border-bottom-color: #f0f;
}

View File

@ -76,7 +76,7 @@ test('being an asshole', () => {
return run('@tailwind utilities', config).then((result) => {
return expect(result.css).toMatchCss(css`
.-mt-\\[10px\\] {
.-mt-\[10px\] {
margin-top: 55px;
}
`)
@ -95,7 +95,7 @@ test('being a real asshole', () => {
return run('@tailwind utilities', config).then((result) => {
return expect(result.css).toMatchCss(css`
.-mt-\\[10px\\] {
.-mt-\[10px\] {
margin-top: -55px;
}
`)
@ -209,7 +209,7 @@ test('arbitrary values', () => {
return run('@tailwind utilities', config).then((result) => {
return expect(result.css).toMatchCss(css`
.-mt-\\[10px\\] {
.-mt-\[10px\] {
margin-top: -10px;
}
`)

View File

@ -21,22 +21,22 @@ test('basic parallel variants', async () => {
.font-normal {
font-weight: 400;
}
.test\\:font-bold *::test {
.test\:font-bold *::test {
font-weight: 700;
}
.test\\:font-medium *::test {
.test\:font-medium *::test {
font-weight: 500;
}
.hover\\:test\\:font-black *::test:hover {
.hover\:test\:font-black *::test:hover {
font-weight: 900;
}
.test\\:font-bold::test {
.test\:font-bold::test {
font-weight: 700;
}
.test\\:font-medium::test {
.test\:font-medium::test {
font-weight: 500;
}
.hover\\:test\\:font-black::test:hover {
.hover\:test\:font-black::test:hover {
font-weight: 900;
}
`)

View File

@ -61,9 +61,9 @@ test('with pseudo-class variants', async () => {
return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.hover\\:scale-x-110,
.focus\\:rotate-3,
.hover\\:focus\\:skew-y-6 {
.hover\:scale-x-110,
.focus\:rotate-3,
.hover\:focus\:skew-y-6 {
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
@ -76,15 +76,15 @@ test('with pseudo-class variants', async () => {
scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
/* --- */
.hover\\:scale-x-110:hover {
.hover\:scale-x-110:hover {
--tw-scale-x: 1.1;
transform: var(--tw-transform);
}
.focus\\:rotate-3:focus {
.focus\:rotate-3:focus {
--tw-rotate: 3deg;
transform: var(--tw-transform);
}
.hover\\:focus\\:skew-y-6:focus:hover {
.hover\:focus\:skew-y-6:focus:hover {
--tw-skew-y: 6deg;
transform: var(--tw-transform);
}
@ -106,8 +106,8 @@ test('with pseudo-element variants', async () => {
return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.before\\:scale-x-110::before,
.after\\:rotate-3::after {
.before\:scale-x-110::before,
.after\:rotate-3::after {
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
@ -120,12 +120,12 @@ test('with pseudo-element variants', async () => {
scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
/* --- */
.before\\:scale-x-110::before {
.before\:scale-x-110::before {
content: '';
--tw-scale-x: 1.1;
transform: var(--tw-transform);
}
.after\\:rotate-3::after {
.after\:rotate-3::after {
content: '';
--tw-rotate: 3deg;
transform: var(--tw-transform);
@ -148,8 +148,8 @@ test('with multi-class variants', async () => {
return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.group-hover\\:scale-x-110,
.peer-focus\\:rotate-3 {
.group-hover\:scale-x-110,
.peer-focus\:rotate-3 {
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
@ -162,11 +162,11 @@ test('with multi-class variants', async () => {
scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
/* --- */
.group:hover .group-hover\\:scale-x-110 {
.group:hover .group-hover\:scale-x-110 {
--tw-scale-x: 1.1;
transform: var(--tw-transform);
}
.peer:focus ~ .peer-focus\\:rotate-3 {
.peer:focus ~ .peer-focus\:rotate-3 {
--tw-rotate: 3deg;
transform: var(--tw-transform);
}
@ -190,8 +190,8 @@ test('with multi-class pseudo-element variants', async () => {
return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.group-hover\\:before\\:scale-x-110::before,
.peer-focus\\:after\\:rotate-3::after {
.group-hover\:before\:scale-x-110::before,
.peer-focus\:after\:rotate-3::after {
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
@ -204,12 +204,12 @@ test('with multi-class pseudo-element variants', async () => {
scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
/* --- */
.group:hover .group-hover\\:before\\:scale-x-110::before {
.group:hover .group-hover\:before\:scale-x-110::before {
content: '';
--tw-scale-x: 1.1;
transform: var(--tw-transform);
}
.peer:focus ~ .peer-focus\\:after\\:rotate-3::after {
.peer:focus ~ .peer-focus\:after\:rotate-3::after {
content: '';
--tw-rotate: 3deg;
transform: var(--tw-transform);
@ -238,8 +238,8 @@ test('with multi-class pseudo-element and pseudo-class variants', async () => {
return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.group-hover\\:hover\\:before\\:scale-x-110::before,
.peer-focus\\:focus\\:after\\:rotate-3::after {
.group-hover\:hover\:before\:scale-x-110::before,
.peer-focus\:focus\:after\:rotate-3::after {
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
@ -252,12 +252,12 @@ test('with multi-class pseudo-element and pseudo-class variants', async () => {
scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
/* --- */
.group:hover .group-hover\\:hover\\:before\\:scale-x-110::before:hover {
.group:hover .group-hover\:hover\:before\:scale-x-110::before:hover {
content: '';
--tw-scale-x: 1.1;
transform: var(--tw-transform);
}
.peer:focus ~ .peer-focus\\:focus\\:after\\:rotate-3::after:focus {
.peer:focus ~ .peer-focus\:focus\:after\:rotate-3::after:focus {
content: '';
--tw-rotate: 3deg;
transform: var(--tw-transform);
@ -485,7 +485,7 @@ test('with borders', async () => {
return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.border,
.md\\:border-2 {
.md\:border-2 {
--tw-border-opacity: 1;
border-color: rgb(229 231 235 / var(--tw-border-opacity));
}
@ -498,7 +498,7 @@ test('with borders', async () => {
border-color: rgb(239 68 68 / var(--tw-border-opacity));
}
@media (min-width: 768px) {
.md\\:border-2 {
.md\:border-2 {
border-width: 2px;
}
}
@ -521,7 +521,7 @@ test('with shadows', async () => {
return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.shadow,
.md\\:shadow-xl {
.md\:shadow-xl {
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
@ -549,11 +549,11 @@ test('with shadows', async () => {
var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.ring-black\\/25 {
.ring-black\/25 {
--tw-ring-color: rgb(0 0 0 / 0.25);
}
@media (min-width: 768px) {
.md\\:shadow-xl {
.md\:shadow-xl {
--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 10px 10px -5px rgb(0 0 0 / 0.04);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
var(--tw-shadow);

View File

@ -22,7 +22,7 @@ it('should safelist strings', () => {
return run('@tailwind utilities', config).then((result) => {
return expect(result.css).toMatchCss(css`
.mt-\\[20px\\] {
.mt-\[20px\] {
margin-top: 20px;
}
@ -39,7 +39,7 @@ it('should safelist strings', () => {
color: rgb(229 231 235 / var(--tw-text-opacity));
}
.hover\\:underline:hover {
.hover\:underline:hover {
text-decoration: underline;
}
`)
@ -73,12 +73,12 @@ it('should safelist based on a pattern regex', () => {
text-transform: uppercase;
}
.hover\\:bg-red-100:hover {
.hover\:bg-red-100:hover {
--tw-bg-opacity: 1;
background-color: rgb(254 226 226 / var(--tw-bg-opacity));
}
.hover\\:bg-red-200:hover {
.hover\:bg-red-200:hover {
--tw-bg-opacity: 1;
background-color: rgb(254 202 202 / var(--tw-bg-opacity));
}
@ -122,12 +122,12 @@ it('should not generate duplicates', () => {
text-transform: uppercase;
}
.hover\\:bg-red-100:hover {
.hover\:bg-red-100:hover {
--tw-bg-opacity: 1;
background-color: rgb(254 226 226 / var(--tw-bg-opacity));
}
.hover\\:bg-red-200:hover {
.hover\:bg-red-200:hover {
--tw-bg-opacity: 1;
background-color: rgb(254 202 202 / var(--tw-bg-opacity));
}

View File

@ -18,11 +18,11 @@ test('class variants are inserted at `@tailwind variants`', async () => {
.font-bold {
font-weight: 700;
}
.hover\\:font-bold:hover {
.hover\:font-bold:hover {
font-weight: 700;
}
@media (min-width: 768px) {
.md\\:font-bold {
.md\:font-bold {
font-weight: 700;
}
}
@ -51,11 +51,11 @@ test('`@tailwind screens` works as an alias for `@tailwind variants`', async ()
.font-bold {
font-weight: 700;
}
.hover\\:font-bold:hover {
.hover\:font-bold:hover {
font-weight: 700;
}
@media (min-width: 768px) {
.md\\:font-bold {
.md\:font-bold {
font-weight: 700;
}
}

View File

@ -10,10 +10,6 @@ export function run(input, config, plugin = tailwind) {
})
}
function syntax(templates) {
return templates.join('')
}
export let css = syntax
export let html = syntax
export let javascript = syntax
export let css = String.raw
export let html = String.raw
export let javascript = String.raw

View File

@ -38,12 +38,12 @@ test('order matters and produces different behaviour', () => {
return run('@tailwind utilities', config).then((result) => {
return expect(result.css).toMatchFormattedCss(css`
.hover\\:file\\:bg-pink-600::file-selector-button:hover {
.hover\:file\:bg-pink-600::file-selector-button:hover {
--tw-bg-opacity: 1;
background-color: rgb(219 39 119 / var(--tw-bg-opacity));
}
.file\\:hover\\:bg-pink-600:hover::file-selector-button {
.file\:hover\:bg-pink-600:hover::file-selector-button {
--tw-bg-opacity: 1;
background-color: rgb(219 39 119 / var(--tw-bg-opacity));
}
@ -70,7 +70,7 @@ describe('custom advanced variants', () => {
return run('@tailwind components;@tailwind utilities', config).then((result) => {
return expect(result.css).toMatchFormattedCss(css`
:where(.prose-headings\\:text-center) :is(h1, h2, h3, h4) {
:where(.prose-headings\:text-center) :is(h1, h2, h3, h4) {
text-align: center;
}
`)
@ -98,11 +98,11 @@ describe('custom advanced variants', () => {
return run('@tailwind components;@tailwind utilities', config).then((result) => {
return expect(result.css).toMatchFormattedCss(css`
:where(.hover\\:prose-headings\\:text-center) :is(h1, h2, h3, h4):hover {
:where(.hover\:prose-headings\:text-center) :is(h1, h2, h3, h4):hover {
text-align: center;
}
:where(.prose-headings\\:hover\\:text-center:hover) :is(h1, h2, h3, h4) {
:where(.prose-headings\:hover\:text-center:hover) :is(h1, h2, h3, h4) {
text-align: center;
}
`)
@ -130,11 +130,11 @@ describe('custom advanced variants', () => {
return run('@tailwind utilities', config).then((result) => {
return expect(result.css).toMatchFormattedCss(css`
.group:hover :where(.group-hover\\:prose-headings\\:text-center) :is(h1, h2, h3, h4) {
.group:hover :where(.group-hover\:prose-headings\:text-center) :is(h1, h2, h3, h4) {
text-align: center;
}
:where(.group:hover .prose-headings\\:group-hover\\:text-center) :is(h1, h2, h3, h4) {
:where(.group:hover .prose-headings\:group-hover\:text-center) :is(h1, h2, h3, h4) {
text-align: center;
}
`)
@ -155,7 +155,7 @@ test('stacked peer variants', async () => {
`
let expected = css`
.peer:disabled:focus:hover ~ .peer-disabled\\:peer-focus\\:peer-hover\\:border-blue-500 {
.peer:disabled:focus:hover ~ .peer-disabled\:peer-focus\:peer-hover\:border-blue-500 {
--tw-border-opacity: 1;
border-color: rgb(59 130 246 / var(--tw-border-opacity));
}
@ -197,7 +197,7 @@ it('should properly handle keyframes with multiple variants', async () => {
}
}
.hover\\:animate-spin:hover {
.hover\:animate-spin:hover {
animation: spin 1s linear infinite;
}
@ -213,7 +213,7 @@ it('should properly handle keyframes with multiple variants', async () => {
}
}
.hover\\:animate-bounce:hover {
.hover\:animate-bounce:hover {
animation: bounce 1s infinite;
}
@ -223,7 +223,7 @@ it('should properly handle keyframes with multiple variants', async () => {
}
}
.focus\\:animate-spin:focus {
.focus\:animate-spin:focus {
animation: spin 1s linear infinite;
}
@ -239,7 +239,7 @@ it('should properly handle keyframes with multiple variants', async () => {
}
}
.focus\\:animate-bounce:focus {
.focus\:animate-bounce:focus {
animation: bounce 1s infinite;
}
`)
@ -263,7 +263,7 @@ test('custom addVariant with nested media & format shorthand', () => {
return expect(result.css).toMatchFormattedCss(css`
@supports (hover: hover) {
@media (print) {
.magic\\:text-center:disabled {
.magic\:text-center:disabled {
text-align: center;
}
}