From b96f342d8ab88f33bfffcf9d208fc59f330e199a Mon Sep 17 00:00:00 2001 From: Adam Wathan Date: Thu, 1 Mar 2018 16:34:40 -0500 Subject: [PATCH] Add initial test suite for processPlugins --- __tests__/processPlugins.test.js | 252 +++++++++++++++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 __tests__/processPlugins.test.js diff --git a/__tests__/processPlugins.test.js b/__tests__/processPlugins.test.js new file mode 100644 index 000000000..75a49b16b --- /dev/null +++ b/__tests__/processPlugins.test.js @@ -0,0 +1,252 @@ +import _ from 'lodash' +import postcss from 'postcss' +import processPlugins from '../src/util/processPlugins' + +function css(nodes) { + return postcss.root({ nodes }).toString() +} + +function objectFitPlugin(variants = []) { + return function ({ rule, addUtilities }) { + addUtilities([ + rule('.object-fill', { + 'object-fit': 'fill', + }), + rule('.object-contain', { + 'object-fit': 'contain', + }), + rule('.object-cover', { + 'object-fit': 'cover', + }), + ], variants) + } +} + +function buttonPlugin() { + return function ({ rule, atRule, addComponents }) { + addComponents([ + rule('.btn-blue', { + 'background-color': 'blue', + 'color': 'white', + 'padding': '.5rem 1rem', + 'border-radius': '.25rem', + }), + rule('.btn-blue:hover', { + 'background-color': 'darkblue', + }), + ]) + } +} + +function containerPlugin() { + return function ({ rule, atRule, addComponents }) { + addComponents([ + rule('.container', { + 'width': '100%', + }), + atRule('@media (min-width: 100px)', [ + rule('.container', { + 'max-width': '100px', + }), + ]), + atRule('@media (min-width: 200px)', [ + rule('.container', { + 'max-width': '200px', + }), + ]), + atRule('@media (min-width: 300px)', [ + rule('.container', { + 'max-width': '300px', + }), + ]) + ]) + } +} + +test('plugins can create utilities', () => { + const config = { + plugins: [ + objectFitPlugin() + ] + } + + const [components, utilities] = processPlugins(config) + + expect(components.length).toBe(0) + expect(css(utilities)).toMatchCss(` + @variants { + .object-fill { + object-fit: fill + } + .object-contain { + object-fit: contain + } + .object-cover { + object-fit: cover + } + } + `) +}) + +test('plugins can create utilities with variants', () => { + const config = { + plugins: [ + objectFitPlugin(['responsive', 'hover', 'group-hover', 'focus']) + ] + } + + const [components, utilities] = processPlugins(config) + + expect(components.length).toBe(0) + expect(css(utilities)).toMatchCss(` + @variants responsive, hover, group-hover, focus { + .object-fill { + object-fit: fill + } + .object-contain { + object-fit: contain + } + .object-cover { + object-fit: cover + } + } + `) +}) + +test('plugins can create components', () => { + const config = { + plugins: [ + buttonPlugin() + ] + } + + const [components, utilities] = processPlugins(config) + + expect(utilities.length).toBe(0) + expect(css(components)).toMatchCss(` + .btn-blue { + background-color: blue; + color: white; + padding: .5rem 1rem; + border-radius: .25rem + } + .btn-blue:hover { + background-color: darkblue + } + `) +}) + +test('plugins can create components with media queries', () => { + const config = { + plugins: [ + containerPlugin() + ] + } + + const [components, utilities] = processPlugins(config) + + expect(utilities.length).toBe(0) + expect(css(components)).toMatchCss(` + .container { + width: 100% + } + @media (min-width: 100px) { + .container { + max-width: 100px + } + } + @media (min-width: 200px) { + .container { + max-width: 200px + } + } + @media (min-width: 300px) { + .container { + max-width: 300px + } + } + `) +}) + +test('plugins can create rules with escaped selectors', () => { + const config = { + plugins: [ + function ({ e, rule, addUtilities }) { + addUtilities([ + rule(`.${e('top-1/4')}`, { + top: '25%', + }) + ], []) + } + ] + } + + const [components, utilities] = processPlugins(config) + + expect(components.length).toBe(0) + expect(css(utilities)).toMatchCss(` + @variants { + .top-1\\/4 { + top: 25% + } + } + `) +}) + +test('plugins can access the current config', () => { + const config = { + screens: { + 'sm': '576px', + 'md': '768px', + 'lg': '992px', + 'xl': '1200px', + }, + plugins: [ + function ({ rule, atRule, addComponents, config }) { + const containerClasses = [ + rule('.container', { + 'width': '100%', + }) + ] + + _.forEach(config.screens, (breakpoint) => { + const mediaQuery = atRule(`@media (min-width: ${breakpoint})`, [ + rule('.container', { 'max-width': breakpoint }) + ]) + containerClasses.push(mediaQuery) + }) + + addComponents(containerClasses) + } + ] + } + + const [components, utilities] = processPlugins(config) + + expect(utilities.length).toBe(0) + expect(css(components)).toMatchCss(` + .container { + width: 100% + } + @media (min-width: 576px) { + .container { + max-width: 576px + } + } + @media (min-width: 768px) { + .container { + max-width: 768px + } + } + @media (min-width: 992px) { + .container { + max-width: 992px + } + } + @media (min-width: 1200px) { + .container { + max-width: 1200px + } + } + `) +})