Skip to content
This repository has been archived by the owner on Dec 28, 2023. It is now read-only.

Develop new major version using PostCSS 8.x API #22

Merged
merged 15 commits into from
Apr 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ jobs:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm install postcss
- run: npm run build --if-present
- run: npm run test:ci
- run: mkdir packdir && cp -r __tests__ src packdir && npm pack --pack-destination packdir
Expand Down Expand Up @@ -73,7 +74,7 @@ jobs:
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm install ava execa cross-env
- run: npm install postcss ava execa cross-env
# - name: Copy test to root dir
# run: cp -r perfectionist-dfd/packdir/__tests_ .
- name: Run tests using Old Node (${{ matrix.node-version }})
Expand Down
19 changes: 14 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,18 @@

## From git log

### v3.0.0-alpha.1 (2022-04-03)

- [Update package-lock.json to v2](https://github.com/danielfdickinson/perfectionist-dfd/commit/cc0d55495ac575d66c1b5ac0f3015811ab8bcb6f) ([Daniel F. Dickinson](mailto:dfdpublic@wildtechgarden.ca))
- [Add and use package clean-publish](https://github.com/danielfdickinson/perfectionist-dfd/commit/ab81064e415136c88fc3abc8ffe1a8fd4572ddda) ([Daniel F. Dickinson](mailto:dfdpublic@wildtechgarden.ca))
- [Install peerDependencies in CI Action](https://github.com/danielfdickinson/perfectionist-dfd/commit/5719ea06f620299661f4772d17d545750aec19b7) ([Daniel F. Dickinson](mailto:dfdpublic@wildtechgarden.ca))
- [Tweak test descriptions \(especially when no error\)](https://github.com/danielfdickinson/perfectionist-dfd/commit/84d261bcb044688bb85a758a76a6ee7497c89162) ([Daniel F. Dickinson](mailto:dfdpublic@wildtechgarden.ca))
- [Tweak require order in cmd.js](https://github.com/danielfdickinson/perfectionist-dfd/commit/14095cd3dc8032da829ec8e73fdf08e188151dd3) ([Daniel F. Dickinson](mailto:dfdpublic@wildtechgarden.ca))
- [+8 more](https://github.com/danielfdickinson/perfectionist-dfd/compare/v2.4.2...v3.0.0-alpha.1)

### v2.4.2 (2022-04-03)

- [Release 2.4.2 \(first dfd stable\)](https://github.com/danielfdickinson/perfectionist-dfd/commit/979ac755e4d8fb4d1b158c28eb0c48b99995e5ac) ([Daniel F. Dickinson](mailto:dfdpublic@wildtechgarden.ca))
- [Release 2.4.2 \(first dfd stable\)](https://github.com/danielfdickinson/perfectionist-dfd/commit/e0d66b0e007c1b04e00b3b842235d0fcf8366793) ([Daniel F. Dickinson](mailto:dfdpublic@wildtechgarden.ca))
- [Fix map tests in options.js](https://github.com/danielfdickinson/perfectionist-dfd/commit/a8b9686d93f45497c95d7a9ba4c2349ded65ac29) ([Daniel F. Dickinson](mailto:dfdpublic@wildtechgarden.ca))
- [Add sourcemap true test and map true test](https://github.com/danielfdickinson/perfectionist-dfd/commit/7a982de63707cde77edc78e32cba950cf65a36ed) ([Daniel F. Dickinson](mailto:dfdpublic@wildtechgarden.ca))
- [Add test to cover map option branch](https://github.com/danielfdickinson/perfectionist-dfd/commit/379add125454f359eed0a79c47bc3287d49acf15) ([Daniel F. Dickinson](mailto:dfdpublic@wildtechgarden.ca))
Expand Down Expand Up @@ -49,7 +58,7 @@

- [#33](https://github.com/danielfdickinson/perfectionist-dfd/pull/33) Update ava to version 0.16.0 🚀 ([greenkeeperio-bot](mailto:support@greenkeeper.io))

#### Commits to pr-update-version
#### Commits to pr-start-dev-new-version

- [Update changelog.](https://github.com/danielfdickinson/perfectionist-dfd/commit/d3515b27a2dca53193963626e1a0f42d41b74435) ([Ben Briggs](mailto:beneb.info@gmail.com))
- [Add options which format hex colours.](https://github.com/danielfdickinson/perfectionist-dfd/commit/ddef43b9841f9162e3c495263894f7cd9fa1acea) ([Ivan Sosnin](mailto:vansosnin@gmail.com))
Expand All @@ -69,7 +78,7 @@

- [#25](https://github.com/danielfdickinson/perfectionist-dfd/pull/25) Ignore commas inside quotes. Fixes \#24 ([Rob Garrison](mailto:wowmotty@gmail.com))

#### Commits to pr-update-version
#### Commits to pr-start-dev-new-version

- [Update changelog.](https://github.com/danielfdickinson/perfectionist-dfd/commit/6d449e68f7e97e9f342186a2452c8a4c2e149960) ([Ben Briggs](mailto:beneb.info@gmail.com))
- [Update CI environment and babel.](https://github.com/danielfdickinson/perfectionist-dfd/commit/56aaf727eb59610412d7c8b1daead8b20a923899) ([Ben Briggs](mailto:beneb.info@gmail.com))
Expand All @@ -92,7 +101,7 @@

- [#20](https://github.com/danielfdickinson/perfectionist-dfd/pull/20) add Atom plugin to readme ([Sindre Sorhus](mailto:sindresorhus@gmail.com))

#### Commits to pr-update-version
#### Commits to pr-start-dev-new-version

- [Update changelog.](https://github.com/danielfdickinson/perfectionist-dfd/commit/5aba30360372c1ef0eb41ed11ccf0690451f69c1) ([Ben Briggs](mailto:beneb.info@gmail.com))
- [Add scss syntax. Fixes \#15.](https://github.com/danielfdickinson/perfectionist-dfd/commit/9571fe70dd35e6ac1c58288474cc80179e400c7b) ([Ben Briggs](mailto:beneb.info@gmail.com))
Expand All @@ -106,7 +115,7 @@

- [#17](https://github.com/danielfdickinson/perfectionist-dfd/pull/17) Use PostCSS 5.0 API ([一丝](mailto:percyley@qq.com))

#### Commits to pr-update-version
#### Commits to pr-start-dev-new-version

- [Update changelog.](https://github.com/danielfdickinson/perfectionist-dfd/commit/4c26bb79ca1ca0a0aa1484c6bbea3110628400b9) ([Ben Briggs](mailto:beneb.info@gmail.com))
- [Add a note in the readme about the Sublime Text plugin.](https://github.com/danielfdickinson/perfectionist-dfd/commit/b321d8b183fcfa7e8172fcaeee13643ac5ae8c9b) ([Ben Briggs](mailto:beneb.info@gmail.com))
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Beautify and/or normalize CSS files. Fork and update of a fork and update of an
With [npm](https://npmjs.org/package/perfectionist-dfd) do:

```sh
npm install perfectionist-dfd --save
npm install postcss perfectionist-dfd --save
```

## Example
Expand Down Expand Up @@ -124,7 +124,7 @@ Default: `expanded`

Pass either `expanded`, `compact` or `compressed`. Note that the `compressed`
format only facilitates simple whitespace compression around selectors &
declarations. For more powerful compression, see [cssnano].
declarations. For more powerful compression, see [cssnano](https://cssnano.co).

##### indentChar

Expand Down
31 changes: 15 additions & 16 deletions __tests__/api.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,29 @@ import { createRequire } from 'module';
import perfectionistDFDNewNode from '../src/index.mjs';
import semver from 'semver';

const require = createRequire(import.meta.url);
const pkg = require('../package.json');
const perfectionistDFDOldNode = require('..');
const requireShim = createRequire(import.meta.url);
const pkg = requireShim('../package.json');
const perfectionistDFDOldNode = requireShim('..');

var perfectionistDFD;
var plugin;

if (semver.gt(process.version, '16.0.0')) {
perfectionistDFD = perfectionistDFDNewNode;
if (semver.gt(process.version, 'v16.0.0')) {
plugin = perfectionistDFDNewNode;
} else {
perfectionistDFD = perfectionistDFDOldNode;
plugin = perfectionistDFDOldNode;
}

function usage (t, instance) {
const input = 'h1 { color: #fff }';
return instance.process(input).then(({css}) => {
t.deepEqual(css, 'h1 {\n color: #fff;\n}\n', 'should be consumed');
});
const output = instance.process(input).css;
return t.deepEqual(output, 'h1 {\n color: #fff;\n}\n', 'should be consumed');
}

ava('can be used as a postcss plugin', usage, postcss().use(perfectionistDFD()));
ava('can be used as a postcss plugin (2)', usage, postcss([ perfectionistDFD() ]));
ava('can be used as a postcss plugin (3)', usage, postcss([ perfectionistDFD ]));
ava('can be used as a postcss plugin', usage, postcss().use(plugin()));
ava('can be used as a postcss plugin (2)', usage, postcss([ plugin() ]));
ava('can be used as a postcss plugin (3)', usage, postcss([ plugin ]));

ava('should use the postcss plugin api', t => {
t.truthy(perfectionistDFD().postcssVersion, 'should be able to access version');
t.deepEqual(perfectionistDFD().postcssPlugin, pkg.name, 'should be able to access name');
ava('use the postcss plugin api', t => {
t.truthy(plugin().postcssVersion, 'should be able to access version');
t.deepEqual(plugin().postcssPlugin, pkg.name, 'should be able to access name');
});
14 changes: 7 additions & 7 deletions __tests__/cli.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,44 +16,44 @@ function setup (args, curdir=__dirname) {
return execa(path.resolve(path.join(__dirname, '../bin/cmd.js')), args, {stripEof: false, cwd: curdir, stripFinalNewline: false});
}

ava('cli: version', t => {
ava('fixture: version', t => {
return setup(['--version']).then(({stdout}) => {
t.deepEqual(stdout, versionString + '\n', 'should report the package version');
});
});

ava('cli: help', t => {
ava('fixture: help', t => {
return setup(['--help']).then(({stdout}) => {
t.deepEqual(stdout, read(path.resolve(path.join(__dirname, './../bin/usage.txt')), 'utf-8'), 'should report the help (usage) text');
});
});

ava('cli: defaults', t => {
ava('fixture: defaults', t => {
return setup([fixture]).then(({stdout}) => {
t.deepEqual(stdout, read(path.resolve(path.join(__dirname, './fixtures/nested.expanded.css')), 'utf-8'), 'should transform the css');
});
});

ava('cli: formatter', t => {
ava('fixture: formatter', t => {
return setup([fixture, '--format', 'compressed']).then(({stdout}) => {
t.deepEqual(stdout, read(path.resolve(path.join(__dirname, './fixtures/nested.compressed.css')), 'utf-8'), 'should transform the css');
});
});

ava('cli: sourcemaps', t => {
ava('fixture: sourcemaps', t => {
return setup([fixture, '--sourcemap']).then(({stdout}) => {
const hasMap = /sourceMappingURL=data:application\/json;base64/.test(stdout);
t.truthy(hasMap, 'should generate a sourcemap');
});
});

ava('cli: output to file', t => {
ava('fixture: output to file', t => {
return setup([fixture, 'out-test'], process.cwd()).then( () => {
t.deepEqual(read('out-test', 'utf-8'), read(path.resolve(path.join(__dirname, './fixtures/nested.expanded.css')), 'utf-8'), 'should transform the css and store in output file');
});
});

ava('cli: throws error on missing input file', async t => {
ava('throws error on missing input file', async t => {
await t.throwsAsync(async () => {
return setup(['/no/such/file.none'], '/');
}, undefined, 'should throw an error');
Expand Down
57 changes: 30 additions & 27 deletions __tests__/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,12 @@ import { createRequire } from 'module';
import semver from 'semver';
import pluginNewNode from '../src/index.mjs';

const __dirname = dirname(fileURLToPath(import.meta.url));
const base = path.resolve(path.join(__dirname,'./fixtures'));

const require = createRequire(import.meta.url);
const pluginOldNode = require('..');
const requireShim = createRequire(import.meta.url);
const pluginOldNode = requireShim('..');

var plugin;

if (semver.gt(process.version, '16.0.0')) {
if (semver.gt(process.version, 'v16.0.0')) {
plugin = pluginNewNode;
} else {
plugin = pluginOldNode;
Expand All @@ -26,6 +23,9 @@ function perfectionistDFD (css, options) {
return plugin.process(css, options).css;
}

const __dirname = dirname(fileURLToPath(import.meta.url));
const base = path.resolve(path.join(__dirname,'./fixtures'));

let specs = fs.readdirSync(base).reduce((tests, css) => {
let [spec, style] = css.split('.');
if (!tests[spec]) {
Expand Down Expand Up @@ -53,36 +53,39 @@ const scss = (css, format) => {
}).css;
};

ava('should handle single line comments', t => {
ava('handle single line comments', t => {
const input = 'h1{\n // test \n color: red;\n}\n';
t.deepEqual(scss(input, 'expanded'), 'h1 {\n // test \n color: red;\n}\n');
t.deepEqual(scss(input, 'compact'), 'h1 {/* test */ color: red; }\n');
t.deepEqual(scss(input, 'compressed'), 'h1{/* test */color:red}');
t.deepEqual(scss(input, 'expanded'), 'h1 {\n // test \n color: red;\n}\n', 'should output the expected result');
t.deepEqual(scss(input, 'compact'), 'h1 {/* test */ color: red; }\n', 'should output the expected result');
t.deepEqual(scss(input, 'compressed'), 'h1{/* test */color:red}', 'should output the expected result');
});

ava('should handle single line comments in @import', t => {
ava('handle single line comments in @import', t => {
const css = 'a, a:visited {\n //@include border-radius(5px);\n @include transition(background-color 0.2s ease);\n}\n';
t.deepEqual(scss(css), css);
t.deepEqual(scss(css), css, 'should output the expected result');
});

let ensureRed = postcss.plugin('ensure-red', () => {
return css => {
let rule = postcss.rule({selector: '*'});
rule.append(postcss.decl({
prop: 'color',
value: 'red',
important: true,
}));
css.append(rule);
let ensureRed = () => {
return {
postcssPlugin: 'ensure-red',
Once(css) {
let rule = postcss.rule({selector: '*'});
rule.append(postcss.decl({
prop: 'color',
value: 'red',
important: true,
}));
css.append(rule);
}
};
});
};

function handleRaws (t, opts = {}) {
return postcss([ensureRed, plugin(opts)]).process('h1 { color: blue }').then(({css}) => {
t.falsy(!!~css.indexOf('undefined'));
return postcss([ensureRed, plugin(opts)]).process('h1 { color: blue }', {from: undefined}).then(({css}) => {
t.falsy(!!~css.indexOf('undefined'), 'should be falsy');
});
}

ava('should handle declarations added without raw properties (default)', handleRaws);
ava('should handle declarations added without raw properties (compact)', handleRaws, {format: 'compact'});
ava('should handle declarations added without raw properties (compressed)', handleRaws, {format: 'compressed'});
ava('handle declarations added without raw properties: default', handleRaws);
ava('handle declarations added without raw properties: compact', handleRaws, {format: 'compact'});
ava('handle declarations added without raw properties: compressed', handleRaws, {format: 'compressed'});
52 changes: 27 additions & 25 deletions __tests__/options.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,87 +3,89 @@ import { createRequire } from 'module';
import semver from 'semver';
import pluginNewNode from '../src/index.mjs';

const require = createRequire(import.meta.url);
const pluginOldNode = require('..');
const requireShim = createRequire(import.meta.url);
const pluginOldNode = requireShim('..');

var plugin;

if (semver.gt(process.version, '16.0.0')) {
if (semver.gt(process.version, 'v16.0.0')) {
plugin = pluginNewNode;
} else {
plugin = pluginOldNode;
}

function perfectionistDFD (css, options) {
return plugin.process(css, options).css;
}

let tests = [{
message: 'should have a configurable indent size',
message: 'configurable indent size',
fixture: 'h1{color:black}',
expected: 'h1 {\n color: black;\n}\n',
options: {indentSize: 2},
}, {
message: 'should have a configurable indent type',
message: 'configurable indent type',
fixture: 'h1{color:black}',
expected: 'h1 {\n color: black;\n}\n',
options: {indentChar: '\t', indentSize: 1},
}, {
message: 'should allow disabling of the cascade',
message: 'disable the cascade',
fixture: 'h1{-webkit-border-radius: 12px; border-radius: 12px; }',
expected: 'h1 {\n -webkit-border-radius: 12px;\n border-radius: 12px;\n}\n',
options: {cascade: false},
}, {
message: 'should convert hex colours to uppercase',
message: 'convert hex colours to uppercase',
fixture: 'h1{color:#fff}',
expected: 'h1 {\n color: #FFF;\n}\n',
options: {colorCase: 'upper'},
}, {
message: 'should expand shorthand hex',
message: 'expand shorthand hex',
fixture: 'h1{color:#fff}',
expected: 'h1 {\n color: #ffffff;\n}\n',
options: {colorShorthand: false},
}, {
message: 'should expand shorthand hex',
message: 'expand shorthand hex (2)',
fixture: 'h1{color:#ffffff}',
expected: 'h1 {\n color: #ffffff;\n}\n',
options: {colorShorthand: false},
}, {
message: 'should not remove units from zero lengths',
message: 'do not remove units from zero lengths',
fixture: 'h1{width:0px}',
expected: 'h1 {\n width: 0px;\n}\n',
options: {zeroLengthNoUnit: false},
}, {
message: 'should add leading zeroes',
message: 'add leading zeroes',
fixture: 'h1{width:.5px}',
expected: 'h1 {\n width: 0.5px;\n}\n',
options: {trimLeadingZero: false},
}, {
message: 'should not trim trailing zeroes',
message: 'do not trim trailing zeroes',
fixture: 'h1{width:10.000px}',
expected: 'h1 {\n width: 10.000px;\n}\n',
options: {trimTrailingZeros: false},
}];

let mapTests = [{
message: 'should expand css',
message: 'expand css',
fixture: 'h1{color:black}',
options: {map: true},
}, {
message: 'should expand css (2)',
message: 'expand css (2)',
fixture: 'h1{color:black}',
options: {map: false, sourcemap: true},
}];

function perfectionistDFD (css, options) {
return plugin.process(css, options).css;
}

ava('perfectionistDFD options', (t) => {
tests.forEach(({fixture, expected, options, message}) => {
t.deepEqual(perfectionistDFD(fixture, options || {}), expected, message);
Object.keys(tests).forEach(key => {
ava(`fixture: ${tests[key]['message']}`, t => {
t.deepEqual(perfectionistDFD(tests[key]['fixture'], tests[key]['options'] || {}), tests[key]['expected'],
'should output the expected result');
});

});

ava('perfectionistDFD map options', (t) => {
mapTests.forEach(({fixture, options, message}) => {
const hasMap = /sourceMappingURL=data:application\/json;base64/.test(perfectionistDFD(fixture, options || {}));
t.truthy(hasMap, message);
Object.keys(mapTests).forEach(key => {
ava(`fixture: ${mapTests[key]['message']}`, t => {
const hasMap = /sourceMappingURL=data:application\/json;base64/.test(perfectionistDFD(mapTests[key]['fixture'], mapTests[key]['options'] || {}));
t.truthy(hasMap, mapTests[key]['message']);
});
});
Loading