diff --git a/build/DevServer.js b/build/DevServer.js index fed9730..3fcb15b 100644 --- a/build/DevServer.js +++ b/build/DevServer.js @@ -32,6 +32,9 @@ var _webpack2 = _interopRequireDefault(_webpack); var _path = require('path'); +var LIVERELOAD_PORT = 35729, + WEB_PORT = 3000; + /** * A lightweight development server that rapidly recompiles the JavaScript and SASS files when they are edited and * updates the page. @@ -61,7 +64,7 @@ var DevServer = (function () { function DevServer(script, style, devDir) { var _this = this; - var port = arguments.length <= 3 || arguments[3] === undefined ? 3000 : arguments[3]; + var port = arguments.length <= 3 || arguments[3] === undefined ? WEB_PORT : arguments[3]; var react = arguments.length <= 4 || arguments[4] === undefined ? true : arguments[4]; _classCallCheck(this, DevServer); @@ -158,7 +161,7 @@ var DevServer = (function () { _createClass(DevServer, [{ key: 'watchSASS', value: function watchSASS(watchDir) { - this.lr.listen(35729); + this.lr.listen(LIVERELOAD_PORT); this.compileSASS(); (0, _watch2['default'])(watchDir, 'scss', this.compileSASS); } diff --git a/build/SASSCompile.js b/build/SASSCompile.js index a1be420..1d85be0 100644 --- a/build/SASSCompile.js +++ b/build/SASSCompile.js @@ -16,13 +16,14 @@ var _nodeSassImportOnce = require('node-sass-import-once'); var _nodeSassImportOnce2 = _interopRequireDefault(_nodeSassImportOnce); -var options = { +var precision = 8, + options = { file: null, outFile: null, importer: _nodeSassImportOnce2['default'], importOnce: { index: true, css: false, bower: false }, includePaths: ['node_modules/bootstrap-sass/assets/stylesheets', 'node_modules'], - precision: 8, + precision: precision, sourceMap: true, sourceMapContents: true }; diff --git a/build/cssMin.js b/build/cssMin.js index 045c658..5a019ba 100644 --- a/build/cssMin.js +++ b/build/cssMin.js @@ -11,6 +11,8 @@ var _cleanCss = require('clean-css'); var _cleanCss2 = _interopRequireDefault(_cleanCss); +var roundingPrecision = -1; + /** * Minifies CSS * @@ -27,7 +29,7 @@ function cssMin(data) { var sourceMappingURL = data.code.match(/\n.+$/)[0], result = new _cleanCss2['default']({ keepSpecialComments: 0, - roundingPrecision: -1, + roundingPrecision: roundingPrecision, sourceMap: data.map, sourceMapInlineSources: true }).minify(data.code); diff --git a/build/watch.js b/build/watch.js index c126762..af504d2 100644 --- a/build/watch.js +++ b/build/watch.js @@ -7,7 +7,8 @@ exports['default'] = watch; var _fbWatchman = require('fb-watchman'); -var client = new _fbWatchman.Client(); +var client = new _fbWatchman.Client(), + ALPHANUMERIC_BASE = 36; /** * Using the Facebook Watchman, watches the directory "dir" for changes of files with extension "type" and runs @@ -26,7 +27,7 @@ var client = new _fbWatchman.Client(); */ function watch(dir, type, callback) { - var subscription = Number(Date.now()).toString(36); + var subscription = Number(Date.now()).toString(ALPHANUMERIC_BASE); client.capabilityCheck({}, function (capabilityErr) { if (capabilityErr) { diff --git a/config/eslint.yml b/config/eslint.yml index 3b6ba5e..e90bb0a 100644 --- a/config/eslint.yml +++ b/config/eslint.yml @@ -101,3 +101,5 @@ rules: id-length: 0 no-negated-condition: 2 no-mixed-spaces-and-tabs: [ 2, false ] + no-magic-numbers: [ 2, { enforceConst: true, detectObjects: true } ] + no-empty-pattern: 2 diff --git a/lib/DevServer.js b/lib/DevServer.js index 90e3667..498f026 100644 --- a/lib/DevServer.js +++ b/lib/DevServer.js @@ -7,6 +7,9 @@ import WebpackDevServer from 'webpack-dev-server'; import webpack from 'webpack'; import {join} from 'path'; +const LIVERELOAD_PORT = 35729, + WEB_PORT = 3000; + /** * A lightweight development server that rapidly recompiles the JavaScript and SASS files when they are edited and * updates the page. @@ -41,7 +44,7 @@ export default class DevServer { server: WebpackDevServer; - constructor(script: string, style: string, devDir: string, port: number = 3000, react: boolean = true) { + constructor(script: string, style: string, devDir: string, port: number = WEB_PORT, react: boolean = true) { const sass = new SASS(), loaders = []; if (react) { @@ -150,7 +153,7 @@ export default class DevServer { * server.watchSASS('/path/to/some/directory'); */ watchSASS(watchDir: string) { - this.lr.listen(35729); + this.lr.listen(LIVERELOAD_PORT); this.compileSASS(); watch(watchDir, 'scss', this.compileSASS); } diff --git a/lib/SASSCompile.js b/lib/SASSCompile.js index e0e8067..c5d2c30 100644 --- a/lib/SASSCompile.js +++ b/lib/SASSCompile.js @@ -3,16 +3,17 @@ import {render} from 'node-sass'; import importer from 'node-sass-import-once'; -const options = { - file: null, - outFile: null, - importer, - importOnce: {index: true, css: false, bower: false}, - includePaths: ['node_modules/bootstrap-sass/assets/stylesheets', 'node_modules'], - precision: 8, - sourceMap: true, - sourceMapContents: true -}; +const precision = 8, + options = { + file: null, + outFile: null, + importer, + importOnce: {index: true, css: false, bower: false}, + includePaths: ['node_modules/bootstrap-sass/assets/stylesheets', 'node_modules'], + precision, + sourceMap: true, + sourceMapContents: true + }; /** * SCSS file compiler diff --git a/lib/cssMin.js b/lib/cssMin.js index 7fca0ca..a1d927d 100644 --- a/lib/cssMin.js +++ b/lib/cssMin.js @@ -2,6 +2,8 @@ import CleanCSS from 'clean-css'; +const roundingPrecision = -1; + /** * Minifies CSS * @@ -17,7 +19,7 @@ export default function cssMin(data: Object): Object { const sourceMappingURL = data.code.match(/\n.+$/)[0], result = new CleanCSS({ keepSpecialComments: 0, - roundingPrecision: -1, + roundingPrecision, sourceMap: data.map, sourceMapInlineSources: true }).minify(data.code); diff --git a/lib/watch.js b/lib/watch.js index 38722b4..182cc97 100644 --- a/lib/watch.js +++ b/lib/watch.js @@ -2,7 +2,8 @@ import {Client} from 'fb-watchman'; -const client = new Client(); +const client = new Client(), + ALPHANUMERIC_BASE = 36; /** * Using the Facebook Watchman, watches the directory "dir" for changes of files with extension "type" and runs @@ -20,7 +21,7 @@ const client = new Client(); * watch(join(__dirname, 'src'), 'js', someFunction); */ export default function watch(dir: string, type: string, callback: Function) { - const subscription = Number(Date.now()).toString(36); + const subscription = Number(Date.now()).toString(ALPHANUMERIC_BASE); client.capabilityCheck({}, function (capabilityErr) { if (capabilityErr) { diff --git a/package.json b/package.json index f3b73bf..b8705af 100644 --- a/package.json +++ b/package.json @@ -44,26 +44,26 @@ "homepage": "https://thealjey.github.io/webcompiler", "dependencies": { "autoprefixer": "^6.0.3", - "babel": "^5.8.23", - "babel-core": "^5.8.25", + "babel": "^5.8.29", + "babel-core": "^5.8.29", "babel-eslint": "^4.1.3", "babel-loader": "^5.3.2", - "babel-runtime": "^5.8.25", - "clean-css": "^3.4.5", - "eslint": "^1.6.0", + "babel-runtime": "^5.8.29", + "clean-css": "^3.4.6", + "eslint": "^1.7.3", "eslint-config-airbnb": "^0.1.0", "eslint-plugin-babel": "^2.1.1", "eslint-plugin-lodash": "^0.1.4", - "eslint-plugin-react": "^3.5.0", + "eslint-plugin-react": "^3.6.3", "fb-watchman": "^1.6.0", "mkdirp": "^0.5.1", - "node-sass": "^3.3.3", + "node-sass": "^3.4.0", "node-sass-import-once": "^1.2.0", - "postcss": "^5.0.9", + "postcss": "^5.0.10", "tiny-lr": "^0.2.1", "uglify-js": "^2.5.0", "webpack": "^1.12.2", - "webpack-dev-server": "^1.12.0" + "webpack-dev-server": "^1.12.1" }, "peerDependencies": { "babel-loader": "5.x", @@ -71,12 +71,12 @@ "react-hot-loader": "1.x" }, "devDependencies": { - "babel-istanbul": "^0.3.20", + "babel-istanbul": "^0.4.0", "coveralls": "^2.11.4", "jasmine-es6": "^0.0.18", "jsdoc": "^3.3.3", "mt-changelog": "^0.6.2", "proxyquire": "^1.7.3", - "release-script": "^0.5.3" + "release-script": "^0.5.4" } } diff --git a/spec/DevServerSpec.js b/spec/DevServerSpec.js index bf633e9..24994e9 100644 --- a/spec/DevServerSpec.js +++ b/spec/DevServerSpec.js @@ -2,6 +2,10 @@ import proxyquire from 'proxyquire'; +const DEFAULT_WEB_PORT = 3000, + WEB_PORT = 8000, + LIVERELOAD_PORT = 35729; + class SASS { feDev(inPath: string, outPath: string, callback: Function) { @@ -73,14 +77,14 @@ describe('DevServer', function () { beforeEach(function () { /* @noflow */ cmp = new DevServer('/path/to/a/script/file.js', '/path/to/a/style/file.scss', - '/path/to/the/development/directory', 8000, false); + '/path/to/the/development/directory', WEB_PORT, false); }); it('assigns a port number', function () { if (!cmp) { return; } - expect(cmp.port).toBe(8000); + expect(cmp.port).toBe(WEB_PORT); }); it('constructs a LiveReload server instance', function () { @@ -234,7 +238,7 @@ describe('DevServer', function () { if (!cmp) { return; } - expect(cmp.lr.listen).toHaveBeenCalledWith(35729); + expect(cmp.lr.listen).toHaveBeenCalledWith(LIVERELOAD_PORT); }); it('compiles SASS on start up', function () { @@ -269,7 +273,7 @@ describe('DevServer', function () { if (!cmp) { return; } - expect(cmp.server.listen).toHaveBeenCalledWith(3000, '0.0.0.0', jasmine.any(Function)); + expect(cmp.server.listen).toHaveBeenCalledWith(DEFAULT_WEB_PORT, '0.0.0.0', jasmine.any(Function)); }); it('prints the error on screen', function () { diff --git a/spec/JSLintSpec.js b/spec/JSLintSpec.js index 6fa1fdd..7a37fef 100644 --- a/spec/JSLintSpec.js +++ b/spec/JSLintSpec.js @@ -3,6 +3,11 @@ import JSLint from '../lib/JSLint'; import {CLIEngine} from 'eslint'; +const MAX_COMPLEXITY = 4, + props = {complexity: [2, MAX_COMPLEXITY]}, + line = 1, + column = 3; + describe('JSLint', function () { let cmp; @@ -13,9 +18,9 @@ describe('JSLint', function () { }); it('should have easily configurable rules', function () { - cmp = new JSLint({complexity: [2, 4]}); + cmp = new JSLint(props); - expect(cmp.linter.options.rules).toEqual(jasmine.objectContaining({complexity: [2, 4]})); + expect(cmp.linter.options.rules).toEqual(jasmine.objectContaining(props)); }); describe('when invoking run', function () { @@ -46,12 +51,12 @@ describe('JSLint', function () { } spyOn(cmp.linter, 'executeOnFiles').and.returnValue({results: [ {filePath: 'first file', messages: [ - {message: 'error message', ruleId: 'some rule', line: 1, column: 3} + {message: 'error message', ruleId: 'some rule', line, column} ]} ]}); cmp.run([], callback); expect(callback).toHaveBeenCalledWith([ - {message: 'error message', ruleId: 'some rule', filePath: 'first file', line: 1, column: 3} + {message: 'error message', ruleId: 'some rule', filePath: 'first file', line, column} ]); }); diff --git a/spec/JSSpec.js b/spec/JSSpec.js index cf16040..dc8f3d1 100644 --- a/spec/JSSpec.js +++ b/spec/JSSpec.js @@ -6,6 +6,14 @@ import JSLint from '../lib/JSLint'; import zlib from 'zlib'; import fs from 'fs'; +const ERROR_COUNT = 3, + LINE1 = 3, + COLUMN1 = 2, + LINE2 = 12, + COLUMN2 = 5, + MAX_COMPLEXITY = 4, + props = {complexity: [2, MAX_COMPLEXITY]}; + describe('JS', function () { let jsMin; @@ -20,7 +28,7 @@ describe('JS', function () { JS = require('../lib/JS'); /* @noflow */ - cmp = new JS({complexity: [2, 4]}); + cmp = new JS(props); }); it('configures Flow', function () { @@ -36,9 +44,7 @@ describe('JS', function () { return; } expect(cmp.linter).toEqual(jasmine.any(JSLint)); - expect(cmp.linter.linter.options.rules).toEqual(jasmine.objectContaining({ - complexity: [2, 4] - })); + expect(cmp.linter.linter.options.rules).toEqual(jasmine.objectContaining(props)); }); }); @@ -149,8 +155,8 @@ describe('JS', function () { } spyOn(cmp.linter, 'run').and.callFake(function (paths, callback) { callback([ - {message: 'error message', ruleId: 'rule id', filePath: 'some file', line: 3, column: 2}, - {message: 'error other message', filePath: 'some other file', line: 12, column: 5} + {message: 'error message', ruleId: 'rule id', filePath: 'some file', line: LINE1, column: COLUMN1}, + {message: 'error other message', filePath: 'some other file', line: LINE2, column: COLUMN2} ]); }); cmp.validate('/path/to/a/file.js', ['/lint/this/directory/too'], spy); @@ -167,10 +173,10 @@ describe('JS', function () { it('logs the error to console', function () { expect(console.log).toHaveBeenCalledWith( '\x1b[41mESLint error\x1b[0m "\x1b[33m%s%s\x1b[0m" in \x1b[36m%s\x1b[0m on \x1b[35m%s:%s\x1b[0m', - 'error message', ' (rule id)', 'some file', 3, 2); + 'error message', ' (rule id)', 'some file', LINE1, COLUMN1); expect(console.log).toHaveBeenCalledWith( '\x1b[41mESLint error\x1b[0m "\x1b[33m%s%s\x1b[0m" in \x1b[36m%s\x1b[0m on \x1b[35m%s:%s\x1b[0m', - 'error other message', '', 'some other file', 12, 5); + 'error other message', '', 'some other file', LINE2, COLUMN2); }); it('does not invoke the callback', function () { @@ -249,7 +255,7 @@ describe('JS', function () { }); it('does not log the successful message', function () { - expect(console.log).toHaveBeenCalledWith('JavaScript compilation errors: %s', 3); + expect(console.log).toHaveBeenCalledWith('JavaScript compilation errors: %s', ERROR_COUNT); expect(console.log).not.toHaveBeenCalledWith('\x1b[32m%s. Compiled %s\x1b[0m', 1, '/path/to/the/input/file.js'); }); diff --git a/spec/SASSCompileSpec.js b/spec/SASSCompileSpec.js index e7e23c4..515ff7d 100644 --- a/spec/SASSCompileSpec.js +++ b/spec/SASSCompileSpec.js @@ -4,6 +4,8 @@ import SASSCompile from '../lib/SASSCompile'; import sass from 'node-sass'; import importer from 'node-sass-import-once'; +const precision = 8; + describe('SASSCompile', function () { describe('no overrides', function () { @@ -47,7 +49,7 @@ describe('SASSCompile', function () { importer, importOnce: {index: true, css: false, bower: false, something: 'here'}, includePaths: ['node_modules/bootstrap-sass/assets/stylesheets', 'node_modules', '/path/to/some/directory'], - precision: 8, + precision, sourceMap: true, sourceMapContents: true }, jasmine.any(Function)); diff --git a/spec/SASSSpec.js b/spec/SASSSpec.js index d3fa257..13fccc7 100644 --- a/spec/SASSSpec.js +++ b/spec/SASSSpec.js @@ -6,6 +6,10 @@ import SASSCompile from '../lib/SASSCompile'; import zlib from 'zlib'; import fs from 'fs'; +const ERROR_COUNT = 3, + line = 12, + column = 8; + describe('SASS', function () { let cssMin; @@ -255,7 +259,7 @@ describe('SASS', function () { return; } spyOn(cmp.compiler, 'run').and.callFake(function (inPath, outPath, callback) { - callback({message: 'could not compile', file: 'some file', line: 12, column: 8}); + callback({message: 'could not compile', file: 'some file', line, column}); }); cmp.webCompile('/path/to/the/input/file.scss', '/path/to/the/output/file.css', Function.prototype); }); @@ -271,7 +275,7 @@ describe('SASS', function () { it('prints the error', function () { expect(console.log).toHaveBeenCalledWith( '\x1b[41mSASS error\x1b[0m "\x1b[33m%s\x1b[0m" in \x1b[36m%s\x1b[0m on \x1b[35m%s:%s\x1b[0m', - 'could not compile', 'some file', 12, 8); + 'could not compile', 'some file', line, column); }); it('does not call cssAutoprefix', function () { @@ -302,7 +306,7 @@ describe('SASS', function () { expect(console.error).toHaveBeenCalledWith('something'); expect(console.error).toHaveBeenCalledWith('bad'); expect(console.error).toHaveBeenCalledWith('happened'); - expect(console.log).toHaveBeenCalledWith('CSS auto-prefix errors: %s', 3); + expect(console.log).toHaveBeenCalledWith('CSS auto-prefix errors: %s', ERROR_COUNT); }); it('does not invoke the callback', function () { diff --git a/spec/cssMinSpec.js b/spec/cssMinSpec.js index 1c012a1..b7651d9 100644 --- a/spec/cssMinSpec.js +++ b/spec/cssMinSpec.js @@ -2,6 +2,8 @@ import proxyquire from 'proxyquire'; +const roundingPrecision = -1; + let options; class CleanCSS { @@ -28,7 +30,7 @@ describe('cssMin', function () { result = cssMin({code: "some css rules\nlast line", map: 'source map contents'}); expect(options).toEqual({ keepSpecialComments: 0, - roundingPrecision: -1, + roundingPrecision, sourceMap: 'source map contents', sourceMapInlineSources: true }); diff --git a/spec/watchSpec.js b/spec/watchSpec.js index 583d1c5..4b7dafb 100644 --- a/spec/watchSpec.js +++ b/spec/watchSpec.js @@ -2,6 +2,8 @@ import proxyquire from 'proxyquire'; +const ALPHANUMERIC_BASE = 36; + class Client { capabilityCheck() {} @@ -21,7 +23,7 @@ describe('watch', function () { cb(); }); callback = jasmine.createSpy('callback'); - spyOn(Date, 'now').and.returnValue(5); + spyOn(Date, 'now'); spyOn(Number.prototype, 'toString').and.returnValue('qwerty'); spyOn(console, 'log'); spyOn(console, 'error'); @@ -40,7 +42,7 @@ describe('watch', function () { return; } watch('qwe', 'rty', Function.prototype); - expect(Number.prototype.toString).toHaveBeenCalledWith(36); + expect(Number.prototype.toString).toHaveBeenCalledWith(ALPHANUMERIC_BASE); }); describe('capabilityCheck error', function () {