tailwindcss/tests/getVariants.test.js
Robin Malfait bc004455bc
Expose context.getVariants for intellisense (#9505)
* add `context.getVariants`

* use `modifier` instead of `label`

* handle `modifySelectors` version

* use reference

* reverse engineer manual format strings if container was touched

* use new positional API for `matchVariant`

* update changelog
2022-10-17 12:38:21 +02:00

141 lines
4.6 KiB
JavaScript

import postcss from 'postcss'
import selectorParser from 'postcss-selector-parser'
import resolveConfig from '../src/public/resolve-config'
import { createContext } from '../src/lib/setupContextUtils'
it('should return a list of variants with meta information about the variant', () => {
let config = {}
let context = createContext(resolveConfig(config))
let variants = context.getVariants()
expect(variants).toContainEqual({
name: 'hover',
isArbitrary: false,
values: [],
selectors: expect.any(Function),
})
expect(variants).toContainEqual({
name: 'group',
isArbitrary: true,
values: expect.any(Array),
selectors: expect.any(Function),
})
// `group-hover` now belongs to the `group` variant. The information exposed for the `group`
// variant is all you need.
expect(variants.find((v) => v.name === 'group-hover')).toBeUndefined()
})
it('should provide selectors for simple variants', () => {
let config = {}
let context = createContext(resolveConfig(config))
let variants = context.getVariants()
let variant = variants.find((v) => v.name === 'hover')
expect(variant.selectors()).toEqual(['&:hover'])
})
it('should provide selectors for parallel variants', () => {
let config = {}
let context = createContext(resolveConfig(config))
let variants = context.getVariants()
let variant = variants.find((v) => v.name === 'marker')
expect(variant.selectors()).toEqual(['& *::marker', '&::marker'])
})
it('should provide selectors for complex matchVariant variants like `group`', () => {
let config = {}
let context = createContext(resolveConfig(config))
let variants = context.getVariants()
let variant = variants.find((v) => v.name === 'group')
expect(variant.selectors()).toEqual(['.group &'])
expect(variant.selectors({})).toEqual(['.group &'])
expect(variant.selectors({ value: 'hover' })).toEqual(['.group:hover &'])
expect(variant.selectors({ value: '.foo_&' })).toEqual(['.foo .group &'])
expect(variant.selectors({ modifier: 'foo', value: 'hover' })).toEqual(['.group\\/foo:hover &'])
expect(variant.selectors({ modifier: 'foo', value: '.foo_&' })).toEqual(['.foo .group\\/foo &'])
})
it('should provide selectors for variants with atrules', () => {
let config = {}
let context = createContext(resolveConfig(config))
let variants = context.getVariants()
let variant = variants.find((v) => v.name === 'supports')
expect(variant.selectors({ value: 'display:grid' })).toEqual(['@supports (display:grid)'])
expect(variant.selectors({ value: 'aspect-ratio' })).toEqual([
'@supports (aspect-ratio: var(--tw))',
])
})
it('should provide selectors for custom plugins that do a combination of parallel variants with modifiers with arbitrary values and with atrules', () => {
let config = {
plugins: [
function ({ matchVariant }) {
matchVariant('foo', (value, { modifier }) => {
return [
`
@supports (foo: ${modifier}) {
@media (width <= 400px) {
&:hover
}
}
`,
`.${modifier}\\/${value} &:focus`,
]
})
},
],
}
let context = createContext(resolveConfig(config))
let variants = context.getVariants()
let variant = variants.find((v) => v.name === 'foo')
expect(variant.selectors({ modifier: 'bar', value: 'baz' })).toEqual([
'@supports (foo: bar) { @media (width <= 400px) { &:hover } }',
'.bar\\/baz &:focus',
])
})
it('should work for plugins that still use the modifySelectors API', () => {
let config = {
plugins: [
function ({ addVariant }) {
addVariant('foo', ({ modifySelectors, container }) => {
// Manually mutating the selector
modifySelectors(({ selector }) => {
return selectorParser((selectors) => {
selectors.walkClasses((classNode) => {
classNode.value = `foo:${classNode.value}`
classNode.parent.insertBefore(classNode, selectorParser().astSync(`.foo `))
})
}).processSync(selector)
})
// Manually wrap in supports query
let wrapper = postcss.atRule({ name: 'supports', params: 'display: grid' })
let nodes = container.nodes
container.removeAll()
wrapper.append(nodes)
container.append(wrapper)
})
},
],
}
let context = createContext(resolveConfig(config))
let variants = context.getVariants()
let variant = variants.find((v) => v.name === 'foo')
expect(variant.selectors({})).toEqual(['@supports (display: grid) { .foo .foo\\:& }'])
})