From 65234e30a89f4752848c73897e40b1dde6800543 Mon Sep 17 00:00:00 2001 From: Anton Nesterov Date: Fri, 8 Apr 2016 21:20:51 +0300 Subject: [PATCH] Use babel and ava instead of mocha --- .babelrc | 3 + .gitignore | 2 + .npmignore | 38 +++++++++++ CHANGELOG.md | 7 ++ package.json | 35 ++++++++-- index.js => src/index.js | 36 +++++----- tests/error.tests.js | 38 +++++++++++ tests/errors.tests.js | 48 -------------- tests/main.tests.js | 139 +++++++++++++++++++-------------------- tests/runTest.helper.js | 14 ++-- 10 files changed, 208 insertions(+), 152 deletions(-) create mode 100644 .babelrc create mode 100644 .npmignore create mode 100644 CHANGELOG.md rename index.js => src/index.js (85%) create mode 100644 tests/error.tests.js delete mode 100644 tests/errors.tests.js diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..c13c5f6 --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["es2015"] +} diff --git a/.gitignore b/.gitignore index 599f454..5dd4954 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,5 @@ jspm_packages # Optional REPL history .node_repl_history +lib + diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..b8cc8aa --- /dev/null +++ b/.npmignore @@ -0,0 +1,38 @@ +### Node ### +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules +jspm_packages + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history + +.babelrc +.gitignore +.travis.yml +node_modules +src diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..f718259 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,7 @@ +# Changlelog + +## [1.0.1] - 2016-04-08 +- Use babel and ava instead of mocha + +## [1.0.0] - 2016-04-07 +- Initial version diff --git a/package.json b/package.json index b45516c..1974e78 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,12 @@ { "name": "usedcss", - "version": "1.0.0", + "version": "1.0.1", "description": "Extract only styles presented in your html files.", - "main": "index.js", + "main": "lib/index.js", "scripts": { - "test": "./node_modules/.bin/eslint *.js tests/*.js && ./node_modules/jscs/bin/jscs *.js tests/*.js && ./node_modules/mocha/bin/mocha tests/*.tests.js" + "build": "./node_modules/.bin/babel src -d lib", + "prepublish": "npm build", + "test": "./node_modules/.bin/eslint src/*js tests/*.js && ./node_modules/.bin/ava && ./node_modules/.bin/jscs src/*.js tests/*.js" }, "repository": { "type": "git", @@ -31,6 +33,16 @@ "node": true, "es6": true, "mocha": true + }, + "parserOptions": { + "sourceType": "module" + }, + "rules": { + "quotes": [ + 2, + "single", + "avoid-escape" + ] } }, "jscsConfig": { @@ -40,6 +52,15 @@ "requireTrailingComma": null, "requireCapitalizedComments": null }, + "ava": { + "require": [ "babel-register" ], + "failFast": true, + "verbose": true, + "babel": "inherit", + "files": [ + "tests/*.tests.js" + ] + }, "dependencies": { "angular-expressions": "^0.3.0", "bluebird": "^3.3.4", @@ -50,10 +71,12 @@ "postcss": "^5.0.19" }, "devDependencies": { + "ava": "^0.14.0", + "babel-cli": "^6.6.5", + "babel-preset-es2015": "^6.6.0", + "babel-register": "^6.7.2", "eslint": "^2.7.0", "eslint-config-defaults": "^9.0.0", - "expect": "^1.16.0", - "jscs": "^2.11.0", - "mocha": "^2.4.5" + "jscs": "^2.11.0" } } diff --git a/index.js b/src/index.js similarity index 85% rename from index.js rename to src/index.js index a798877..7dd520a 100644 --- a/index.js +++ b/src/index.js @@ -1,16 +1,16 @@ 'use strict'; -const Promise = require('bluebird'); -const fs = Promise.promisifyAll(require('fs')); -const glob = Promise.promisify(require('multi-glob').glob); -const postcss = require('postcss'); -const noop = require('node-noop').noop; -const cheerio = require('cheerio'); -const expressions = require('angular-expressions'); -const isRegex = require('is-regex'); +import Promise from 'bluebird'; +import {readFile} from 'fs'; +import {glob as glob} from 'multi-glob'; +import postcss from 'postcss'; +import {noop} from 'node-noop'; +import cheerio from 'cheerio'; +import expressions from 'angular-expressions'; +import isRegex from 'is-regex'; module.exports = postcss.plugin('usedcss', (options) => { var htmls = []; - return function(css) { + return (css) => { return new Promise((resolve, reject) => { if (!options.html) { reject('No html files specified.'); @@ -28,11 +28,11 @@ module.exports = postcss.plugin('usedcss', (options) => { reject('ignoreRegexp option should contain regular expressions.'); return; } - if (options.ngclass && typeof options.ngclass != 'boolean') { + if (options.ngclass && typeof options.ngclass !== 'boolean') { reject('ngclass option should be boolean.'); return; } - if (options.ignoreNesting && typeof options.ignoreNesting != 'boolean') { + if (options.ignoreNesting && typeof options.ignoreNesting !== 'boolean') { reject('ignoreNesting option should be boolean.'); return; } @@ -45,10 +45,10 @@ module.exports = postcss.plugin('usedcss', (options) => { promise = Promise.resolve(); } promise.then(() => { - return glob(options.html) + return Promise.promisify(glob)(options.html) .then((files) => { return Promise.map(files, (file) => { - return fs.readFileAsync(file).then((content) => { + return Promise.promisify(readFile)(file).then((content) => { htmls.push(cheerio.load(content.toString())); return Promise.resolve(); }); @@ -97,21 +97,21 @@ module.exports = postcss.plugin('usedcss', (options) => { // sounds hacky, but it works promises.push( Promise.map(rule.selectors, (selector) => { - var promise; + var pr; if (options.ignoreRegexp) { - promise = Promise.map(options.ignoreRegexp, (item) => { + pr = Promise.map(options.ignoreRegexp, (item) => { if (item.test(selector)) { return Promise.reject(); } }); } else { - promise = Promise.resolve(); + pr = Promise.resolve(); } - return promise.then(() => { + return pr.then(() => { // remove pseudo-classes from selectors selector = selector.replace(/::?[a-zA-Z-]*$/g, ''); if (options.ignoreNesting) { - selector = selector.replace(/^.*( |>|<)/g, '') + selector = selector.replace(/^.*( |>|<)/g, ''); } return Promise.map(htmls, (html) => { if ( diff --git a/tests/error.tests.js b/tests/error.tests.js new file mode 100644 index 0000000..bf1f15b --- /dev/null +++ b/tests/error.tests.js @@ -0,0 +1,38 @@ +import test from 'ava'; +import {runTest} from './runTest.helper.js'; + +test('Should retun error if there is no html files specified', t => { + return runTest({html: null}).catch(err => { + t.is(err, 'No html files specified.'); + }); +}); + +test('Should retun error if ignore is not an array', t => { + return runTest({ignore: 'test'}).catch(err => { + t.is(err, 'ignore option should be an array.'); + }); +}); + +test('Should return error if ignoreRegexp is not an array', t => { + return runTest({ignoreRegexp: 'test'}).catch(err => { + t.is(err, 'ignoreRegexp option should be an array.'); + }); +}); + +test('Should retun error if ignoreRegexp contains not a regexp', t => { + return runTest({ignoreRegexp: ['test']}).catch(err => { + t.is(err, 'ignoreRegexp option should contain regular expressions.'); + }); +}); + +test('Should retun error if ngclass is not boolean', t => { + return runTest({ngclass: 'test'}).catch(err => { + t.is(err, 'ngclass option should be boolean.'); + }); +}); + +test('Should retun error if ignoreNesting is not boolean', t => { + return runTest({ignoreNesting: 'test'}).catch(err => { + t.is(err, 'ignoreNesting option should be boolean.'); + }); +}); diff --git a/tests/errors.tests.js b/tests/errors.tests.js deleted file mode 100644 index 85f0555..0000000 --- a/tests/errors.tests.js +++ /dev/null @@ -1,48 +0,0 @@ -const expect = require('expect'); -const runTest = require('./runTest.helper.js'); - -describe('errors', () => { - it('Should retun error if there is no html files specified.', (done) => { - runTest({html: null}).catch((err) => { - expect(err).toBe('No html files specified.'); - done(); - }); - }); - - it('Should retun error if ignore is not an array', (done) => { - runTest({ignore: 'test'}).catch((err) => { - expect(err).toBe('ignore option should be an array.'); - done(); - }); - }); - - it('Should retun error if ignoreRegexp is not an array', (done) => { - runTest({ignoreRegexp: 'test'}).catch((err) => { - expect(err).toBe('ignoreRegexp option should be an array.'); - done(); - }); - }); - - it('Should retun error if ignoreRegexp contains not a regexp', (done) => { - runTest({ignoreRegexp: ['test']}).catch((err) => { - expect(err).toBe( - 'ignoreRegexp option should contain regular expressions.' - ); - done(); - }); - }); - - it('Should retun error if ngclass is not boolean', (done) => { - runTest({ngclass: 'test'}).catch((err) => { - expect(err).toBe('ngclass option should be boolean.'); - done(); - }); - }); - - it('Should retun error if ignoreNesting is not boolean', (done) => { - runTest({ignoreNesting: 'test'}).catch((err) => { - expect(err).toBe('ignoreNesting option should be boolean.'); - done(); - }); - }); -}); diff --git a/tests/main.tests.js b/tests/main.tests.js index e5c4370..71d49ce 100644 --- a/tests/main.tests.js +++ b/tests/main.tests.js @@ -1,90 +1,83 @@ -const expect = require('expect'); -const runTest = require('./runTest.helper.js'); +import test from 'ava'; +import {runTest} from './runTest.helper.js'; -describe('main', () => { - it('Should remove unused css classes', (done) => { - runTest().then((result) => { - expect(result.css).toBe( - '.test1 .test2 { color: red }\n' + - '.test10,.test2 { color: pink; }\n.' + - 'test1:after { content: \'\'; }\n' + - '.test2::before { content: \'\'; }\n' - ); - done(); - }); +test('Should remove unused css classes', t => { + return runTest().then(result => { + t.is(result.css, + '.test1 .test2 { color: red }\n' + + '.test10,.test2 { color: pink; }\n.' + + 'test1:after { content: \'\'; }\n' + + '.test2::before { content: \'\'; }\n' + ); }); +}); - it('Should save ng-class classes', (done) => { - runTest({ngclass: true}).then((result) => { - expect(result.css).toBe( - '.test1 .test2 { color: red }\n' + - '.test10,.test2 { color: pink; }\n' + - '.test1:after { content: \'\'; }\n' + - '.test2::before { content: \'\'; }\n' + - '.test1 .test3 { color: white; }\n' + - '.test1 .test4 { color: orange; }\n' - ); - done(); - }); - }); - it('Should ignore nesting', (done) => { - runTest({ignoreNesting: true}).then((result) => { - expect(result.css).toBe( - '.test1 .test2 { color: red }\n' + - '.test10,.test2 { color: pink; }\n' + - '.test1:after { content: \'\'; }\n' + - '.test2::before { content: \'\'; }\n' + - '.nested .test1 { color: blue; }\n' + - '.nested>.test2 { color: yellow;}\n' - ); - done(); - }); +test('Should save ng-class classes', t => { + return runTest({ngclass: true}).then(result => { + t.is(result.css, + '.test1 .test2 { color: red }\n' + + '.test10,.test2 { color: pink; }\n' + + '.test1:after { content: \'\'; }\n' + + '.test2::before { content: \'\'; }\n' + + '.test1 .test3 { color: white; }\n' + + '.test1 .test4 { color: orange; }\n' + ); }); +}); - it('Should work with ignore option', (done) => { - runTest({ignore: ['.remove']}).then((result) => { - expect(result.css).toBe( - '.test1 .test2 { color: red }\n' + - '.test10,.test2 { color: pink; }\n' + - '.test1:after { content: \'\'; }\n' + - '.test2::before { content: \'\'; }\n' + - '.remove { color: black; }\n' - ); - done(); - }); +test('Should ignore nesting', t => { + return runTest({ignoreNesting: true}).then(result => { + t.is(result.css, + '.test1 .test2 { color: red }\n' + + '.test10,.test2 { color: pink; }\n' + + '.test1:after { content: \'\'; }\n' + + '.test2::before { content: \'\'; }\n' + + '.nested .test1 { color: blue; }\n' + + '.nested>.test2 { color: yellow;}\n' + ); }); +}); - it('Ignore should also ignore nesting if ignoreNesting is enabled', - (done) => { - runTest({ - ignore: ['.nesting .remove'], - ignoreNesting: true - }).then((result) => { - expect(result.css).toBe( - '.test1 .test2 { color: red }\n' + - '.test10,.test2 { color: pink; }\n' + - '.test1:after { content: \'\'; }\n' + - '.test2::before { content: \'\'; }\n' + - '.nested .test1 { color: blue; }\n' + - '.nested>.test2 { color: yellow;}\n' + - '.remove { color: black; }\n' - ); - done(); - }); - } - ); +test('Should work with ignore option', t => { + return runTest({ignore: ['.remove']}).then(result => { + t.is(result.css, + '.test1 .test2 { color: red }\n' + + '.test10,.test2 { color: pink; }\n' + + '.test1:after { content: \'\'; }\n' + + '.test2::before { content: \'\'; }\n' + + '.remove { color: black; }\n' + ); + }); +}); - it('Should work with ignoreRegexp option', (done) => { - runTest({ignoreRegexp: [/.*remo.*/]}).then((result) => { - expect(result.css).toBe( - '.test1 .test2 { color: red }\n' + +test('Ignore should also ignore nesting if ignoreNesting is enabled', + t => { + return runTest({ + ignore: ['.nesting .remove'], + ignoreNesting: true + }).then(result => { + t.is(result.css, + '.test1 .test2 { color: red }\n' + '.test10,.test2 { color: pink; }\n' + '.test1:after { content: \'\'; }\n' + '.test2::before { content: \'\'; }\n' + + '.nested .test1 { color: blue; }\n' + + '.nested>.test2 { color: yellow;}\n' + '.remove { color: black; }\n' ); - done(); }); + } +); + +test('Should work with ignoreRegexp option', t => { + return runTest({ignore: ['.remove']}).then(result => { + t.is(result.css, + '.test1 .test2 { color: red }\n' + + '.test10,.test2 { color: pink; }\n' + + '.test1:after { content: \'\'; }\n' + + '.test2::before { content: \'\'; }\n' + + '.remove { color: black; }\n' + ); }); }); diff --git a/tests/runTest.helper.js b/tests/runTest.helper.js index a4c5f4f..f909ce0 100644 --- a/tests/runTest.helper.js +++ b/tests/runTest.helper.js @@ -1,9 +1,9 @@ -const postcss = require('postcss'); -const Promise = require('bluebird'); -const usedcss = require('../index.js'); -const readFile = Promise.promisify(require('fs').readFile); +import postcss from 'postcss'; +import Promise from 'bluebird'; +import usedcss from '../src/index.js'; +import {readFile} from 'fs'; -module.exports = (options, file) => { +export function runTest(options, file) { if (!file) { file = `${__dirname}/test.css`; } @@ -15,7 +15,7 @@ module.exports = (options, file) => { html: [`${__dirname}/test.html`] }; } - return readFile(file).then((content) => { + return Promise.promisify(readFile)(file).then((content) => { return postcss([usedcss(options)]).process(content.toString()); }); -}; +}