Skip to content

Commit

Permalink
Merge pull request tailwindlabs#2224 from tailwindlabs/fix-multiline-…
Browse files Browse the repository at this point in the history
…apply

Fix multiline @apply values
  • Loading branch information
RobinMalfait authored Aug 21, 2020
2 parents 2903811 + f15cace commit c79b0b9
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 1 deletion.
113 changes: 113 additions & 0 deletions __tests__/applyComplexClasses.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,61 @@ function run(input, config = {}) {
test('it copies class declarations into itself', () => {
const output = '.a { color: red; } .b { color: red; }'

expect.assertions(2)

return run('.a { color: red; } .b { @apply a; }').then(result => {
expect(result.css).toMatchCss(output)
expect(result.warnings().length).toBe(0)
})
})

test('apply values can contain tabs', () => {
const input = `
.a {
@apply p-4\tm-4;
}
`

const expected = `
.a {
margin: 1rem;
padding: 1rem;
}
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
})
})

test('apply values can contain newlines', () => {
const input = `
.a {
@apply p-4 m-4
flex flex-col;
}
`

const expected = `
.a {
display: flex;
flex-direction: column;
margin: 1rem;
padding: 1rem;
}
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
})
})

test('selectors with invalid characters do not need to be manually escaped', () => {
const input = `
.a\\:1\\/2 { color: red; }
Expand All @@ -29,6 +78,8 @@ test('selectors with invalid characters do not need to be manually escaped', ()
.b { color: red; }
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand All @@ -46,6 +97,8 @@ test('it removes important from applied classes by default', () => {
.b { color: red; }
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand All @@ -63,6 +116,8 @@ test('applied rules can be made !important', () => {
.b { color: red !important; }
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand All @@ -79,12 +134,16 @@ test('cssnext custom property sets are no longer supported', () => {
}
`

expect.assertions(1)

return run(input).catch(e => {
expect(e).toMatchObject({ name: 'CssSyntaxError' })
})
})

test('it fails if the class does not exist', () => {
expect.assertions(1)

return run('.b { @apply a; }').catch(e => {
expect(e).toMatchObject({ name: 'CssSyntaxError' })
})
Expand All @@ -110,6 +169,8 @@ test('applying classes that are defined in a media query is supported', () => {
}
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(output)
expect(result.warnings().length).toBe(0)
Expand Down Expand Up @@ -149,6 +210,8 @@ test('applying classes that are used in a media query is supported', () => {
}
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(output)
expect(result.warnings().length).toBe(0)
Expand Down Expand Up @@ -176,6 +239,8 @@ test('it matches classes that include pseudo-selectors', () => {
}
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(output)
expect(result.warnings().length).toBe(0)
Expand Down Expand Up @@ -212,6 +277,8 @@ test('it matches classes that have multiple rules', () => {
}
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(output)
expect(result.warnings().length).toBe(0)
Expand Down Expand Up @@ -244,6 +311,8 @@ test('applying a class that appears multiple times in one selector', () => {
}
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(output)
expect(result.warnings().length).toBe(0)
Expand All @@ -259,6 +328,8 @@ test('you can apply utility classes that do not actually exist as long as they w
.foo { margin-top: 1rem; }
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand All @@ -271,6 +342,8 @@ test('the shadow lookup is only used if no @tailwind rules were in the source tr
.foo { @apply mt-4; }
`

expect.assertions(1)

return run(input).catch(e => {
expect(e).toMatchObject({ name: 'CssSyntaxError' })
})
Expand Down Expand Up @@ -301,6 +374,8 @@ test('you can apply a class that is defined in multiple rules', () => {
}
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand All @@ -321,6 +396,8 @@ test('you can apply a class that is defined in a media query', () => {
}
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand All @@ -339,6 +416,8 @@ test('you can apply pseudo-class variant utilities', () => {
}
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand All @@ -359,6 +438,8 @@ test('you can apply responsive pseudo-class variant utilities', () => {
}
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand Down Expand Up @@ -397,6 +478,8 @@ test('you can apply the container component', () => {
}
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand Down Expand Up @@ -428,6 +511,8 @@ test('classes are applied according to CSS source order, not apply order', () =>
}
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand Down Expand Up @@ -458,6 +543,8 @@ test('you can apply utilities with multi-class selectors like group-hover varian
}
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand Down Expand Up @@ -488,6 +575,8 @@ test('you can apply classes recursively', () => {
}
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand Down Expand Up @@ -523,6 +612,8 @@ test('applied classes are always inserted before subsequent declarations in the
}
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand Down Expand Up @@ -554,6 +645,8 @@ test('adjacent rules are collapsed after being applied', () => {
}
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand Down Expand Up @@ -602,6 +695,8 @@ test('applying a class applies all instances of that class, even complex selecto
}
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand Down Expand Up @@ -635,6 +730,8 @@ test('you can apply classes to rules within at-rules', () => {
}
`

expect.assertions(2)

return run(input).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand All @@ -658,6 +755,8 @@ describe('using apply with the prefix option', () => {
},
])

expect.assertions(2)

return run(input, config).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand All @@ -682,6 +781,8 @@ describe('using apply with the prefix option', () => {
},
])

expect.assertions(2)

return run(input, config).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand All @@ -700,6 +801,8 @@ describe('using apply with the prefix option', () => {
},
])

expect.assertions(1)

return run(input, config).catch(e => {
expect(e).toMatchObject({ name: 'CssSyntaxError' })
})
Expand All @@ -723,6 +826,8 @@ describe('using apply with the prefix option', () => {
},
])

expect.assertions(2)

return run(input, config).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand All @@ -747,6 +852,8 @@ describe('using apply with the prefix option', () => {
},
])

expect.assertions(2)

return run(input, config).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand Down Expand Up @@ -792,6 +899,8 @@ describe('using apply with the prefix option', () => {
},
])

expect.assertions(2)

return run(input, config).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand All @@ -815,6 +924,8 @@ describe('using apply with the prefix option', () => {
},
])

expect.assertions(2)

return run(input, config).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand Down Expand Up @@ -843,6 +954,8 @@ test('you can apply utility classes when a selector is used for the important op
},
])

expect.assertions(2)

return run(input, config).then(result => {
expect(result.css).toMatchCss(expected)
expect(result.warnings().length).toBe(0)
Expand Down
2 changes: 1 addition & 1 deletion src/flagged/applyComplexClasses.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ function processApplyAtRules(css, lookupTree, config) {
importantEntries,
applyUtilityNames,
important = importantEntries.length > 0,
] = _.partition(applyRule.params.split(' '), n => n === '!important')
] = _.partition(applyRule.params.split(/[\s\t\n]+/g), n => n === '!important')

const currentUtilityNames = extractUtilityNames(rule.selector)

Expand Down

0 comments on commit c79b0b9

Please sign in to comment.