Skip to content

Commit b2b2b39

Browse files
committed
better docs and tests, add append/prepend plugins opts
1 parent 46ae518 commit b2b2b39

File tree

3 files changed

+89
-29
lines changed

3 files changed

+89
-29
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ css.plugins.push(lost())
6363
| **rucksack** | Options passed directly to [rucksack](http://simplaio.github.io/rucksack/docs/#options) | |
6464
| **parser** | custom css parser if desired. pass `false` to use the default css parser | `sugarss` |
6565
| **minify** | Minifies the css output by removing excess spaces and line breaks | `false` |
66+
| **appendPlugins** | Adds a single plugin or array of plugins after all the defaults | |
67+
| **prependPlugins** | Adds a single plugin or array of plugins before all the defaults | |
6668

6769
### License & Contributing
6870

lib/index.js

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,61 @@ let postcssImport = require('postcss-import')
33
let cssnext = require('postcss-cssnext')
44
let rucksack = require('rucksack-css')
55

6+
/**
7+
* Primary export, formats options and returns an object with intelligent
8+
* defaults.
9+
* @param {Object} [options={}] - options object
10+
* @param {Function} [options.parser=sugarss] - if false, is set to undefined
11+
* @param {Array|String} options.path - passed to import plugin
12+
* @param {String} options.root - passed to import plugin
13+
* @param {Array} options.browsers - passed to cssnext plugin
14+
* @param {Object} options.features - passed to cssnext plugin
15+
* @param {Boolean} options.warnForDuplicates - passed to cssnext plugin
16+
* @param {Object} options.rucksack - passed to rucksack plugin
17+
* @param {Boolean} options.minify - whether or not to add the minify plugin
18+
* @return {Object} valid postcss options object
19+
*/
620
module.exports = (options = {}) => {
721
// sugarss by default unless false or custom parser
822
let parser = options.parser || sugarss
923
if (options.parser === false) parser = undefined
1024
options.path = options.path ? Array.prototype.concat(options.path) : []
1125

1226
// standard options merge
13-
const importOpt = selectiveMerge(options, ['root', 'path'])
14-
const cssnextOpt = selectiveMerge(options, ['browsers', 'features', 'warnForDuplicates'])
27+
const importOpt = selectKeys(options, ['root', 'path'])
28+
const cssnextOpt = selectKeys(options, ['browsers', 'features', 'warnForDuplicates'])
1529

16-
// define normal plugin list
30+
// define default plugin list
1731
const plugins = [
1832
postcssImport(importOpt),
1933
cssnext(cssnextOpt),
2034
rucksack(options.rucksack)
2135
]
2236

37+
// append and prepend plugins if needed
38+
if (options.appendPlugins) {
39+
plugins.push(...Array.prototype.concat(options.appendPlugins))
40+
}
41+
42+
if (options.prependPlugins) {
43+
plugins.unshift(...Array.prototype.concat(options.prependPlugins))
44+
}
45+
2346
// add cssnano if minify config present
2447
if (options.minify) plugins.push(require('cssnano')())
2548

2649
return {parser, plugins}
2750
}
2851

29-
function selectiveMerge (opts, optNames) {
52+
/**
53+
* Given an options object and an array of key names, return an object filtered
54+
* to contain only the keys in the optNames array, if they exist on the options
55+
* object.
56+
* @param {Object} opts - full options object
57+
* @param {Array} optNames - keys to filter
58+
* @return {Object} object filtered for the specific keys
59+
*/
60+
function selectKeys (opts, optNames) {
3061
return optNames.reduce((m, opt) => {
3162
if (typeof opts[opt] !== 'undefined') { m[opt] = opts[opt] }; return m
3263
}, {})

test/index.js

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,65 @@ const cssStandardsRewired = rewire('../lib')
33
const cssStandards = require('../lib')
44
const test = require('ava')
55

6-
test('basic', (t) => {
7-
cssStandardsRewired.__set__('postcssImport', (opts) => {
8-
t.truthy(opts.root === 'test')
9-
t.truthy(opts.path[0] === 'test/test1')
10-
t.truthy(opts.path[1] === 'test/test2')
11-
})
6+
test('passes parser opt correctly', (t) => {
7+
const out = cssStandards({ parser: 'test' })
8+
const out2 = cssStandards({ parser: false })
9+
t.is(out.parser, 'test')
10+
t.is(out2.parser, undefined)
11+
})
1212

13-
cssStandardsRewired.__set__('cssnext', (opts) => {
14-
t.truthy(opts.features === 'test')
15-
t.truthy(opts.browsers === 'test')
16-
t.truthy(opts.warnForDuplicates === 'test')
13+
test('passes import opts correctly', (t) => {
14+
const undo = cssStandardsRewired.__set__('postcssImport', (opts) => {
15+
t.is(opts.root, 'test')
16+
t.is(opts.path[0], 'test')
1717
})
18+
cssStandardsRewired({ root: 'test', path: 'test' })
19+
undo()
20+
})
1821

19-
cssStandardsRewired.__set__('rucksack', (opts) => {
20-
t.truthy(opts === 'test')
22+
test('passes cssnext opts correctly', (t) => {
23+
const undo = cssStandardsRewired.__set__('cssnext', (opts) => {
24+
t.is(opts.browsers, 'test')
25+
t.is(opts.features, 'test')
26+
t.is(opts.warnForDuplicates, 'test')
2127
})
22-
23-
const out1 = cssStandardsRewired({
24-
parser: false,
25-
path: ['test/test1', 'test/test2'],
26-
features: 'test',
28+
cssStandardsRewired({
2729
browsers: 'test',
28-
warnForDuplicates: 'test',
29-
rucksack: 'test',
30-
root: 'test'
30+
features: 'test',
31+
warnForDuplicates: 'test'
32+
})
33+
undo()
34+
})
35+
36+
test('passes rucksack opts correctly', (t) => {
37+
const undo = cssStandardsRewired.__set__('rucksack', (opts) => {
38+
t.is(opts, 'test')
3139
})
40+
cssStandardsRewired({ rucksack: 'test' })
41+
undo()
42+
})
3243

33-
t.truthy(out1.plugins.length === 3)
34-
t.falsy(out1.parser)
44+
test('default plugins working', (t) => {
45+
const out = cssStandards()
46+
t.is(out.plugins.length, 3)
47+
})
3548

36-
const out2 = cssStandards({ minify: true })
49+
test('minify option working', (t) => {
50+
const out = cssStandards({ minify: true })
51+
t.is(out.plugins.length, 4)
52+
t.is(out.plugins[out.plugins.length - 1].postcssPlugin, 'cssnano')
53+
})
54+
55+
test('appendPlugins option', (t) => {
56+
const out = cssStandards({ appendPlugins: ['test'] })
57+
const out2 = cssStandards({ appendPlugins: 'test' })
58+
t.truthy(out.plugins[out.plugins.length - 1] === 'test')
59+
t.truthy(out2.plugins[out.plugins.length - 1] === 'test')
60+
})
3761

38-
t.truthy(out2.parser)
39-
t.truthy(out2.plugins.length === 4)
62+
test('prependPlugins option', (t) => {
63+
const out = cssStandards({ prependPlugins: ['test'] })
64+
const out2 = cssStandards({ prependPlugins: 'test' })
65+
t.truthy(out.plugins[0] === 'test')
66+
t.truthy(out2.plugins[0] === 'test')
4067
})

0 commit comments

Comments
 (0)